【问题标题】:How to iterate in a cartesian product of lists如何迭代列表的笛卡尔积
【发布时间】:2012-08-27 13:35:51
【问题描述】:

我想在 for 循环中使用 3 个(或任意数量的)列表和任意数量的元素进行迭代,例如:

from itertools import izip
for x in izip(["AAA", "BBB", "CCC"], ["M", "Q", "S", "K", "B"], ["00:00", "01:00", "02:00", "03:00"]):
    print x

但它给了我:

('AAA', 'M', '00:00')
('BBB', 'Q', '01:00')
('CCC', 'S', '02:00')

我想要:

('AAA', 'M', '00:00')
('AAA', 'M', '01:00')
('AAA', 'M', '02:00')
.
.

('CCC', 'B', '03:00')

其实我想要这个:

for word, letter, hours in [cartesian product of 3 lists above]
    if myfunction(word,letter,hours):
       var_word_letter_hours += 1

【问题讨论】:

    标签: python list for-loop loops


    【解决方案1】:

    您想使用列表中的product

    from itertools import product
    
    for word, letter, hours in product(["AAA", "BBB", "CCC"], ["M", "Q", "S", "K", "B"], ["00:00", "01:00", "02:00", "03:00"]):
    

    演示:

    >>> from itertools import product
    >>> for word, letter, hours in product(["AAA", "BBB", "CCC"], ["M", "Q", "S", "K", "B"], ["00:00", "01:00", "02:00", "03:00"]):
    ...     print word, letter, hours
    ... 
    AAA M 00:00
    AAA M 01:00
    AAA M 02:00
    AAA M 03:00
    ...
    CCC B 00:00
    CCC B 01:00
    CCC B 02:00
    CCC B 03:00
    

    【讨论】:

      【解决方案2】:

      使用itertools.product:

      import itertools
      
      for x in itertools.product(["AAA", "BBB", "CCC"],
                                 ["M", "Q", "S", "K", "B"],
                                 ["00:00", "01:00", "02:00", "03:00"]):
          print x
      

      输出:

      ('AAA', 'M', '00:00')
      ('AAA', 'M', '01:00')
      ...
      ('CCC', 'B', '02:00')
      ('CCC', 'B', '03:00')
      

      【讨论】:

        【解决方案3】:

        仅作记录,另一种解决方案只是嵌套for循环:

        for a in ["AAA", "BBB", "CCC"]:
            for b in ["M", "Q", "S", "K", "B"]:
               for c in ["00:00", "01:00", "02:00", "03:00"]:
                   x = (a, b, c)
                   # Use x ...
        

        在我看来,这比必须找出/记住itertools.product 函数的作用要清楚得多。使用它的唯一充分理由是,如果您处于更抽象的情况;例如您需要将迭代器传递给函数,而不是立即对其进行迭代,或者如果您有任意列表想要获取笛卡尔积(在这种情况下,您可以使用 product(*lists))。

        【讨论】:

        • 如果您需要在不同循环级别进行额外处理,此解决方案更有意义。但是,OP 只想遍历三元组,而这种方法必须手动构建。嵌套的for 循环是它们添加的缩进与列表一样多,这对于可读性来说可能是一个真正的问题。
        • 如果在编译时不知道嵌套循环的数量(或任何你想在 python 中调用编译时),这也不好
        • @FinanceGuyThatCantCode 我已经在我的回答中明确提到过,我说过“如果你有一个任意的列表列表想要获取笛卡尔积”是不好的
        猜你喜欢
        • 2017-09-28
        • 2011-01-26
        • 2012-03-24
        • 1970-01-01
        • 2017-07-15
        • 2012-01-03
        • 2021-10-22
        • 2011-07-10
        • 2021-05-06
        相关资源
        最近更新 更多