【问题标题】:Iterate over all combinations of values in multiple lists in Python迭代Python中多个列表中的所有值组合
【发布时间】:2013-05-05 11:36:55
【问题描述】:

给定多个可能不同长度的列表,我想迭代所有值组合,每个列表中的一项。例如:

first = [1, 5, 8]
second = [0.5, 4]

那么我希望的输出是:

combined = [(1, 0.5), (1, 4), (5, 0.5), (5, 4), (8, 0.5), (8, 4)]

我想遍历 combined 列表。我该如何完成这项工作?

【问题讨论】:

    标签: python iteration


    【解决方案1】:

    itertools.product 应该可以解决问题。

    >>> import itertools
    >>> list(itertools.product([1, 5, 8], [0.5, 4]))
    [(1, 0.5), (1, 4), (5, 0.5), (5, 4), (8, 0.5), (8, 4)]
    

    请注意,itertools.product 返回一个迭代器,因此如果您只打算对其进行一次迭代,则无需将其转换为列表。

    例如。

    for x in itertools.product([1, 5, 8], [0.5, 4]):
        # do stuff
    

    【讨论】:

    • 如果second = [0.5, 4, 1] 并且我们认为输出(1, 4) 与输出(4, 1) 相同呢?
    • @TheRedPea (假设您在第一个列表中有一个 4,并且您只想要结果中的唯一输出)我认为您之后只需使用 set(tuple(sorted(lst)) for lst in itertools.product(...)) 或类似的东西进行过滤那个。
    • @Volatility ,是否也可以添加这些组合:(0.5, 1), (0.5, 5), (0.5, 8), (4, 1), (4, 5), (4, 8)
    • 这个解决方案的问题是,如果我们给产品方法提供列表列表,它就不起作用。我们应该只给它分开的列表,只有在这种情况下它才能返回产品。如果我错了,请纠正我。
    • @Pedram 是正确的。如果您只有列表列表,则需要使用 * 将其解压缩为单独的参数(请参阅 this)。
    【解决方案2】:

    这可以通过使用list comprehension 来实现,而无需任何导入。使用您的示例:

    first = [1, 5, 8]
    second = [0.5, 4]
    
    combined = [(f,s) for f in first for s in second]
    
    print(combined)
    # [(1, 0.5), (1, 4), (5, 0.5), (5, 4), (8, 0.5), (8, 4)]
    

    【讨论】:

    • 这应该是当前 Python 的最佳答案。我可能是错的,但我认为最初的最佳答案是针对 Python 2 的——也许像这个答案这样的 list comp 是不可能的。
    • 我不同意@msm1089,具有列表推导的解决方案仅适用于已知的少量原始列表。相反,itertools 方法可以覆盖任意数量的列表,例如itertools.product(*my_lists)。这是更通用的,有时是必要的。
    • 实际上,我同意你的看法@CedricDruck。最通用的是 itertools 方法。但是,如您所说,如果只有少量的小列表,那么列表组合可能会更好。
    • 好点,@CedricDruck,这两种方法都有自己的位置。不过,我认为大多数人都希望尽可能避免再次导入。 OP 在这里提出的具体问题是少数已知列表,因此答案非常适用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    相关资源
    最近更新 更多