带生成器的Python listcomp

2024-03-28 17:48:19 发布

您现在位置:Python中文网/ 问答频道 /正文

如果生成器生成的单词在列表中是唯一的,我想将它添加到列表中,最多10次。你知道吗

word_list = []
for i in range(10):
    next_word = next(test)
    if next_word not in word_list:
        word_list.append(next_word)

这就是我试图理解的

word_list = [next(test) for next(test) in range(10) if next(test) not in word_list]

我遇到了两个问题

  • 我无法检查这个词是否已经在listcomp的列表中
  • 每次使用next(test)时,它都会新生成一个生成器,因此无法添加下一个生成器

如何用listcomp实现第一个代码段?你知道吗


Tags: intest列表forif代码段notrange
3条回答

首先,让我们解决发电机问题。正如您所提到的,您只希望在每个迭代中使用next(test)一次。最简单的解决方案是循环测试,这与调用next完全相同:

word_list = [s for _, s in zip(range(10), test)]

此代码将从生成器中提取前10个单词。现在,您希望它只接受唯一的值。如果您不介意顺序,您可以将其转换为集合,而不是在列表comp中检查:

word_list = set([s for _, s in zip(range(10), test)])

如果您不介意顺序,可以使用OrderSet recipe,或者更简单地使用OrderedDict:

from collections import OrderedDict    
word_list = [t[0] for t in OrderedDict({s:_ for _, s in zip(range(10), test)})]

最终会得到与for循环相同的输出。 这个解决方案不太好读,我必须说我更喜欢使用旧的nice for循环。你知道吗

或者更像@tobias\u k建议的那样:

from collections import OrderedDict
from itertools import islice
word_list = list(OrderedDict({s:s for s in islice(test, 0, 10)}))

可能有点猜测,但我认为您真的想从生成器中提取下10个唯一值,在这种情况下,列表理解可能很棘手,甚至您的循环示例也不会真正做到这一点。要获得10个下一个唯一值:

 def gen():
     for n in [1,2,3,4,5,5,5,5,5,5,5,5,6,7,8,9,10,11,12]:
         yield n

 l = []
 g = gen()
 while len(l) < 11:
     try:
         v = next(g)
     except StopIteration:
         break
     if v not in l:
         l.append(v)
 print l

你可以用这样的基因不需要range()函数:

word_list = [item for item in test if item not in word_list]

或者,如果需要调用n个项,请使用itertools:

import itertools

word_list = [item for item in itertools.islice(test,10) if item not in word_list]

也可以使用zip func:

word_list = [item for item,ret in zip(test,range(10)) if item not in word_list]

或者如果你想得到前n项唯一,我想你不能这样做与listcomp

相关问题 更多 >