如何在Python中使用生成器比较可迭代对象?
如何在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]
非常希望能够得到一个解决我的问题的解决方案,并附带解释。
通过使用生成器在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对此进行了修改,感谢(对同样内容的更短评论已被删除)。