如何将一系列 IF 语句转换为 Pythonic 代码行?

How do I turn a series of IF statements into a Pythonic code line?

我正在努力提高我的列表理解能力。我想将以下内容变成 Pythonic 代码行:

# Sample sentence
sample_sentence = "Once upon a time, three people walked into a bar, Once upon a time, three people walked into a bar"

# Empty list to hold words from sentence
words = []

# Empty lists to hold longest and shortest items
longest = []
shortest = []

# Pythonic method to split sentence into list of words
words = [c for c in sample_sentence.split()]

# Non-Pythonic routine to find the shortest and longest words
for i in words:
    if len(i) <= shortest_len:
        # shortest = [] # Reset list
        shortest.append(i)
    if len(i) >= longest_len:
        longest.append(i)

print(f"Shortest item: {', '.join(shortest)}")
print(f"Longest item: {', '.join(longest)}")

我已经尝试创建 非 Pythonic 例程的 Pythonic 版本 来查找最短和最长的单词:

shortest = [i for i in words if len(i) <= shortest_len: shortest.append(i) ]
print(shortest)
longest = [i for i in words if len(i) >= longest_len: longest.append(i)]
print(longest)

但是它得到一个无效的语法错误。

如何构造以上两行代码,是否可以使用一个 Pythonic 行将两者结合起来?

为您的列表理解案例尝试此操作以解决语法错误 -

shortest = [i for i in words if len(i) <= shortest_len]
print(shortest)
longest = [i for i in words if len(i) >= longest_len]
print(longest)

您还可以使用 words = sample_sentence.split()

而不是 words = [c for c in sample_sentence.split()]

要解决 SyntaxError,您必须只删除 : shortest.append(i): longest.append(i)。列表将如预期那样。

is it possible to use a single Pythonic line to combine the two ?

不,不可能在一行中建立两个列表。 (除了你当然可以将两个列表结构放在一行之外:

shortest = [i for i in words if len(i) <= shortest_len: shortest.append(i)]; longest = [i for i in words if len(i) >= longest_len: longest.append(i)]

)。但我不认为那是你的目标......

不要错误地认为一切都必须是一个聪明的一行。最好编写您将来可以查看并确切知道它将做什么的代码。在我看来,这是一种非常 Pythonic 的脚本编写方式。是的,可以进行改进,但如果不需要,请不要优化。这个脚本是读两句,如果是读整本书我们可以改进。

正如评论中所说,每个人都有自己对“Pythonic”的定义和自己的格式。就个人而言,我认为当您的代码正在做什么非常清楚时,您不需要注释。例如,当您的变量命名为 sample_sentence.

时,您不需要注释“Sample Sentence”
sample_sentence = "Once upon a time, three people walked into a bar, Once upon a time, three people walked into a bar"

words = sample_sentence.split()
words.sort(key=len)

short_len = len(words[0])
long_len = len(words[-1])

shortest_words = [word for word in words if len(word) == short_len]
longest_words = [word for word in words if len(word) == long_len]

print(f"Shortest item: {', '.join(shortest_words)}")
print(f"Longest item: {', '.join(longest_words)}")

这是一行代码,用于查找句子中每个单词的长度并将它们从最短到最长排序:

words_len = sorted(list(set([(c, len(c)) for c in sample_sentence.split()])), key=lambda t: t[1])

或者正如我在评论中指出的那样,您可以通过这样做来达到同样的目的:

words = sorted(list(set(sample_sentence.split())), key=len)
print(f"shortest: {words[0]}\nlongest: {words[-1]}") 

获取最短和最长单词的替代代码:

sample_sentence = "Once upon a time, three people walked into a bar, Once upon a time, three people walked into a bar"

my_list = list(set([(token,len(token)) for token in sample_sentence.split()]))
longest_word = ', '.join(i[0] for i in my_list if i[1]==max([x[1] for x in my_list]))
shortest_word = ', '.join(i[0] for i in my_list if i[1]==min([x[1] for x in my_list]))
print(f"longest words: {longest_word}")
print(f"shortest words: {shortest_word}")

输出

longest words: people, walked
shortest words: a

首先,你需要在某处定义shortest_lenlongest_len。你可以使用这个:

shortest_len = min([len(word) for word in words])
longest_len = max([len(word) for word in words])

shortest = [word for word in words if len(word) == shortest_len]
longest = [word for word in words if len(word) == longest_len]

可以将这两行合并成

shortest, longest = [word for word in words if len(word) == shortest_len], [word for word in words if len(word) == longest_len]

如果你真的想疯狂,你可以压缩到这样:

sample_sentence = "Once upon a time, three people walked into a bar, Once upon a time, three people walked into a bar"

print(f"Shortest item: {', '.join([word for word in [c for c in sample_sentence.split()] if len(word) == min([len(word) for word in words])])}")
print(f"Longest item: {', '.join([word for word in [c for c in sample_sentence.split()] if len(word) == max([len(word) for word in words])])}")

甚至将这两个合二为一 print 得到一个单行:

sample_sentence = "Once upon a time, three people walked into a bar, Once upon a time, three people walked into a bar"

print(f"Shortest item: {', '.join([word for word in [c for c in sample_sentence.split()] if len(word) == min([len(word) for word in words])])}\nLongest item: {', '.join([word for word in [c for c in sample_sentence.split()] if len(word) == max([len(word) for word in words])])}")

但是,正如@big_bad_bison 已经指出的那样,最短的解决方案并不总是与最佳解决方案和代码的可读性相同(对您自己而言,需要数月或数年;或对其他人而言,如果您需要在团队中工作或寻求帮助)则更为重要。

许多单行代码 不是 干净的 Pythonic,因为它们使一行代码太长。 PEP 8 - Style Guide for Python Code (definitely suggested reading!)清晰停留:

Limit all lines to a maximum of 79 characters.