【问题标题】:How do I compare iterables using generators in Python?如何在 Python 中使用生成器比较可迭代对象?
【发布时间】:2020-03-31 11:22:12
【问题描述】:

我有以下问题。我必须实现一个作为生成器的函数,它需要任意数量的迭代。可以假设迭代器每次都以相同的顺序发布它们的元素。该函数应返回所有可迭代对象(视图断言)中位于同一位置的所有元素:

def intersect(*iterables, **kwiterables):
    for obj in iterables:
        #need help here :)
        #already tried something like:
        # obj = (var for var in obj if var in iterables)
    yield obj

#asserts:
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]

很高兴能通过解释解决我的问题。

【问题讨论】:

  • 我建议对每个函数调用的每个可迭代(仅一次)使用next()(并保留相同的可迭代)
  • iterables 是一个迭代列表。因此,您的 for obj in iterables 不会比较不同列表之间的元素,obj 始终是列表之一!例如。对于intersect((1,2,3), (1,"x",3)),您的obj 在第一次迭代期间为(1,2,3),在第二次迭代期间为(1,"x",3)

标签: python generator


【解决方案1】:

您可以使用zip 内置函数并行迭代所有可迭代对象。

例如,zip(it_a, it_b, it_c) 迭代三元组(a, b, c),其中a 来自it_ab 来自it_bc 来自it_c。第一个三元组包含迭代的第一个元素,第二个包含第二个元素,依此类推。您可以将其与 * 语法结合起来,以传递任意数量的参数以获取 zip(*iterables),它会生成包含所有元素的 n 元组。 (您可以进一步传递*iterables*kwiterables.values() 以组合iterableskwiterables。)最后,一旦您获得值的“行”,您只需要检查该行的所有元素是否相等.

最终结果可能如下所示(通过您的测试):

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

【讨论】:

  • 迭代 zip(*iterables,*kwiterables.values()): 也可以
  • @Jean-FrançoisFabre 我已经修改了答案以包含它,谢谢。 (删除了相同效果的简短评论。)
猜你喜欢
  • 1970-01-01
  • 2023-03-20
  • 2017-12-18
  • 1970-01-01
  • 1970-01-01
  • 2016-04-16
  • 1970-01-01
  • 2021-06-10
  • 1970-01-01
相关资源
最近更新 更多