Python 具有嵌套循环和if条件的列表理解,以及新列表的成员资格
这是我的常规嵌套循环,带有if条件,以及新列表的成员资格:Python 具有嵌套循环和if条件的列表理解,以及新列表的成员资格,python,algorithm,loops,if-statement,list-comprehension,Python,Algorithm,Loops,If Statement,List Comprehension,这是我的常规嵌套循环,带有if条件,以及新列表的成员资格: wordlist = ["micro", "macro", "stats"] letterlist = [] for aword in wordlist: for aletter in aword: if aletter not in letterlist: letterlist.append(aletter) print(letterlist) 它打印出的字母没有重复:['m',
wordlist = ["micro", "macro", "stats"]
letterlist = []
for aword in wordlist:
for aletter in aword:
if aletter not in letterlist:
letterlist.append(aletter)
print(letterlist)
它打印出的字母没有重复:['m','i','c','r','o','a','s','t']
当我尝试使用列表理解进行相同操作时,我只能通过嵌套循环:
wordlist = ["micro", "macro", "stats"]
letterlist = [aletter for aword in wordlist for aletter in aword]
print(letterlist)
这将打印所有具有重复项的字母:['m','i','c','r','o','m','a','c','r','o','s','t','a','t','s']
不幸的是,这不起作用:
wordlist = ["micro", "macro", "stats"]
letterlist = [[if aletter not in letterlist] for aword in wordlist for aletter in aword]
问题:基于上面的示例,如何使用列表理解执行nestloop with if语句
提前感谢您可以将输出保存在单独的列表中,如:
wordlist = ["micro", "macro", "stats"]
res=[]
[res.append(aletter) for aword in wordlist for aletter in aword if aletter not in res]
print(res)
或
希望这有帮助 您可以按如下方式使用集合理解:
letterlist = { aletter for aword in wordlist for aletter in aword}
默认设置不会附加重复的值。而且它更紧凑
值得一提的是,在列表中使用in运算符时,它的时间复杂度是线性的,而在集合中,它的时间复杂度几乎是恒定的 否。您不能使用列表理解来执行此操作,因为您需要创建已看到的字母列表。我相信你最好的做法是使用for循环。如果您需要保持字母的顺序,请同时使用列表和设置列表以保持顺序,设置为每个字母都有O1成员资格测试。如果顺序不重要,那么只需使用集合理解,即{word中的字母与单词中的字母列表} 请注意,使用列表理解的副作用(即创建已看到的字母的第二个列表)不是pythonic 时间安排
另一个解决方案是,只需在自己的代码中添加两行代码。 您可以将列表转换为字典,根据定义,它接受唯一的值,如果您需要将其作为列表,则可以再次转换为列表
for aword in wordlist:
for aletter in aword:
if aletter not in letterlist:
letterlist.append(aletter)
letterdict = list(dict.fromkeys(letterlist)) #list to dictionary
letterlist = list(letterdict)
您可以按以下方式执行此操作
from collections import OrderedDict
wordlist = ["micro", "macro", "stats"]
sol = list(OrderedDict.fromkeys(''.join(wordlist)).keys())
print(sol)
输出
['m', 'i', 'c', 'r', 'o', 'a', 's', 't']
你也可以使用
sol = [*OrderedDict.fromkeys(''.join(wordlist)).keys()]
使用dict,它可以按如下方式完成
sol = list(dict((i,1) for i in ''.join(wordlist)).keys())
在此处添加@alexander solution
sol = list(dict.fromkeys(''.join(wordlist)))
您可以使用dict.fromkeys和chain.from\u iterable函数:
在Python 3.6及以下版本中,您需要用OrderedDict替换dict。谢谢!第二个解决方案是我已经解决的,但是我希望是否有一种方法可以在一个连续的列表理解代码中继续第一个解决方案。对于第一个解决方案,我认为您必须创建一个单独的列表来存储res.@Mick-上面的列表集[…]选项很好-如果列表中的顺序不重要的话。保持输出的顺序对您来说重要吗?@S3DEV谢谢您的提问。顺序很重要,因为我想使用列表理解来复制与上面If语句相同的嵌套循环;您正在创建一个不必要的列表,该列表可能很长而且很昂贵。for循环完成了同样的事情,并且更加清晰。列表理解只能用于创建列表。是否有办法仅使用列表理解来解决此问题?集合用于唯一值,使用Set Comp可以非常容易地做到这一点。就性能而言,列表上的In运算符具有线性复杂度,而在集合上它使用哈希,因此速度要快得多,而且就可读性而言,您不必编写if stat。回答您的问题,我认为这是不可能的。@adnamuttaleb感谢您的反馈。现在使用集合更有意义,因为在成员资格中具有比集合慢的线性复杂性。我不知道这一部分。正如OP在评论中所说的,顺序很重要,所以集合不起作用。@Alexander对此表示感谢,我没有阅读评论,解决方案已更新。当然,对于python 3.7+cython 3.6+,使用dict和OrderedDict也可以使用相同的解决方案。它既高效又短,因此我认为它是最好的。更简单的是,listdict.fromkeys.joinwordlist这是对解决方案的一个很好的补充,因为.joinwordlist需要在内存中实例化整个列表,而chain.from_iterableswordlist只访问每个字母,因此在内存方面效率更高。鉴于这一改进,我现在认为这是迄今为止最好的解决方案。@Alexander这是迄今为止最好的解决方案:
sol = [*OrderedDict.fromkeys(''.join(wordlist)).keys()]
sol = list(dict((i,1) for i in ''.join(wordlist)).keys())
sol = list(dict.fromkeys(''.join(wordlist)))
from itertools import chain
list(dict.fromkeys(chain.from_iterable(wordlist)))
# ['m', 'i', 'c', 'r', 'o', 'a', 's', 't']