如何在Python中使用生成器比较可迭代对象?

7 浏览
0 Comments

如何在Python中使用生成器比较可迭代对象?

我有以下问题。我需要实现一个作为生成器的函数,它预期接收任意数量的可迭代对象。可以假设这些可迭代对象每次都以相同的顺序发出它们的元素。该函数应该返回所有在所有可迭代对象中处于相同位置的元素(查看断言):

def intersect(*iterables, **kwiterables):
    for obj in iterables:
        # 在这里需要帮助 :)
        # 已经尝试了一些类似的方法:
        # obj = (var for var in obj if var in iterables)
    yield obj
# 断言:
assert list(intersect((1,2,3))) == [1,2,3]
assert list(intersect((1,2,3), (1,"x",3))) == [1,3]
assert list(intersect([1,1,1,1,1,1,1,1,1], [1,2,1,2,1,2,1,2,1,2], k = [3,3,1,3,3,1,3,3,1,3,3,1])) == [1,1]

非常希望能够得到一个解决我的问题的解决方案,并附带解释。

0
0 Comments

通过使用生成器在Python中比较可迭代对象,可以使用内建函数`zip`来同时迭代所有可迭代对象。例如,`zip(it_a, it_b, it_c)`会迭代三元组`(a, b, c)`,其中`a`来自`it_a`,`b`来自`it_b`,`c`来自`it_c`。第一个三元组包含可迭代对象的第一个元素,第二个三元组包含第二个元素,依此类推。您可以结合使用`*`语法来传递任意数量的参数,以获取`zip(*iterables)`,它会生成包含所有元素的n元组(还可以同时传递`*iterables`和`*kwiterables.values()`来合并`iterables`和`kwiterables`)。最后,一旦您获得了值的“行”,您只需要检查该行的所有元素是否相等。

最终的结果可以像这样(通过了您的测试):

def intersect(*iterables, **kwiterables):
    for objs in zip(*iterables, *kwiterables.values()):
        first = objs[0]
        if all(o == first for o in objs[1:]):
            yield first

也可以使用`iterate over zip(*iterables,*kwiterables.values()):`进行操作。

-FrançoisFabre对此进行了修改,感谢(对同样内容的更短评论已被删除)。

0