首页 > 解决方案 > For循环到字典理解正确翻译(Python)

问题描述

我需要在列表中为字母表中的每个字母找到最长的字符串。我的第一个直接方法如下所示:

alphabet = ["a","b", ..., "z"]
text = ["ane4", "anrhgjt8", "andhjtje9", "ajhe5", "]more_crazy_words"]
result = {key:"" for key in alphabet} # create a dictionary

# go through all words, if that word is longer than the current longest, save it
for word in text: 
    if word[0].lower() in alphabet and len(result[word[0].lower()]) < len(word):
        result[word[0].lower()] = word.lower()
print(result)

返回:

{'a': 'andhjtje9'}

正如它应该做的那样。

为了练习字典理解,我试图用一行来解决这个问题:

result2 = {key:"" for key in alphabet}
result2 = {word[0].lower(): word.lower() for word in text if word[0].lower() in alphabet and len(result2[word[0].lower()]) < len(word)}

我只是将 if 语句复制到了理解循环中……但是 results2 是:

{'a': 'ajhe5'}

有人可以解释一下为什么会这样吗?我觉得我在第一个循环中所做的完全一样......感谢您的帮助!

标签: pythonfor-loopdictionary-comprehension

解决方案


List / Dict / Set - 理解不能在构建自身时引用它们自己 - 这就是为什么你没有得到你想要的。

可以使用复杂的字典理解来执行此操作 - 在排序列表上的 collections.groupby 的帮助下,这可能如下所示:

from string import ascii_lowercase
from itertools import groupby 

text = ["ane4", "anrhgjt8", "andhjtje9", "ajhe5", "]more_crazy_words"] 

d = {key:sorted(value, key=len)[-1] 
 for key,value in groupby((s for s in sorted(text) 
                           if s[0].lower() in frozenset(ascii_lowercase)), 
                          lambda x:x[0].lower())}
print(d) # {'a': 'andhjtje9'}

或者

text = ["ane4", "anrhgjt8", "andhjtje9", "ajhe5", "]more_crazy_words"] 
 
d = {key:next(value) for key,value in groupby(
    (s for s in sorted(text, key=lambda x: (x[0],-len(x))) 
     if s[0].lower() in frozenset(ascii_lowercase)), 
     lambda x:x[0].lower())}

print(d) # {'a': 'andhjtje9'}

或其他几种方式......但你为什么要这样做?

将其用作 for 循环会更清晰,更易于理解,并且在这种情况下,可能会更好地遵循 python 的禅宗。

通过运行阅读有关 python 之禅的信息:

import this

推荐阅读