1 回答

TA贡献1817条经验 获得超6个赞
itertools.product返回一个迭代器,迭代器一般都是“single-pass”的(可能有例外)。一旦一个元素被迭代,它就不会被再次迭代。
但是,您可以itertools.product在两个地方使用结果,一次作为 for 的参数,一次作为 for 的starmap参数compress。因此,如果starmap“弹出”一个元素,product那么下一次compress“弹出”来自同一产品的元素,它将接收下一个元素(不是同一个元素)。
在大多数情况下,我建议不要将此类迭代器分配为变量,正是因为它们的“单程”性质。
所以一个明显的解决方法是两次生成产品:
matched_mask = starmap(is_in, product(to_find, some_sentences))
matched = compress(product(to_find, some_sentences), matched_mask)
print(list(matched))
# [('hello', 'hello to you'), ('hello', ' hello and bye'), ('bye', ' hello and bye'), ('bye', 'bye bye')]
在这种情况下,我认为生成器函数中的循环比使用 multiple 更具可读性itertools:
from itertools import product
def func(to_find, some_sentences):
for sub, sentence in product(to_find, some_sentences):
if sub in sentence:
yield sub, sentence
然后像这样使用它:
>>> to_find = ['hello','bye']
>>> some_sentences = ['hello to you', ' hello and bye', 'bye bye']
>>> list(func(to_find, some_sentences))
[('hello', 'hello to you'),
('hello', ' hello and bye'),
('bye', ' hello and bye'),
('bye', 'bye bye')]
或者如果你喜欢单线:
>>> [(sub, sentence) for sub, sentence in product(to_find, some_sentences) if sub in sentence]
[('hello', 'hello to you'),
('hello', ' hello and bye'),
('bye', ' hello and bye'),
('bye', 'bye bye')]
添加回答
举报