【问题标题】:Python itertoolsPython 迭代工具
【发布时间】:2019-02-22 09:58:37
【问题描述】:

我有 4 个包含不同数量元素的列表。我想输出单个列表元素的 3 项的所有可能组合。 一种方法是 itertool.combinations (),但使用 .combinations 我只能组合列表中的项目。

列表:

colors      = ["blue", "yellow", "green", "black", "magenta"]
numbers     = [1,2,3,4,5,6,7,8]
material = ["beton", "wood", "stone"]
names      = ["Susi", "Klara", "Claire", "Moni"]

结果应该是:

[blue, 1, beton], [blue, 1, Susi], [blue, 2, beton]…

【问题讨论】:

  • 你能展示一下你尝试过的东西吗
  • 所以基本上你想结合材料和名称?因为您的预期输出不清楚

标签: python itertools


【解决方案1】:

可以使用product()函数:

from itertools import product

list(product(colors, numbers, material + names))

【讨论】:

  • 我不认为 OP 要求结合材料和名称。我认为这种混乱的根源在于,在预期的输出中,OP 只提到了几个组合,而且碰巧这些组合中没有出现名称。
【解决方案2】:

使用productchain 名称和材料:

from itertools import chain, product

colors      = ["blue", "yellow", "green", "black", "magenta"]
numbers     = [1,2,3,4,5,6,7,8]
material = ["beton", "wood", "stone"]
names      = ["Susi", "Klara", "Claire", "Moni"]

out = product(colors, numbers, chain(material, names))

部分输出:

for i in range(10):
    print(next(out))

('blue', 1, 'beton')
('blue', 1, 'wood')
('blue', 1, 'stone')
('blue', 1, 'Susi')
('blue', 1, 'Klara')
('blue', 1, 'Claire')
('blue', 1, 'Moni')
('blue', 2, 'beton')
('blue', 2, 'wood')
('blue', 2, 'stone')

【讨论】:

    【解决方案3】:

    你需要组合来自不同列表的项目是itertools.product,你需要从一组四个列表中选择三个列表是itertools.combinations

    我在下面提供了一个简化缩短这两个工具的应用示例:

    In [57]: from itertools import product, combinations                                      
    
    In [58]: a, b, c = ['stone','concrete'], ['Jane','Mary'], [1,2,3]                         
    
    In [59]: for l1, l2 in combinations((a,b,c), 2): 
        ...:     for i1, i2 in product(l1,l2): 
        ...:         print(i1, i2)                                                            
    stone Jane
    stone Mary
    concrete Jane
    concrete Mary
    stone 1
    stone 2
    stone 3
    concrete 1
    concrete 2
    concrete 3
    Jane 1
    Jane 2
    Jane 3
    Mary 1
    Mary 2
    Mary 3
    
    In [60]:                                                                                  
    

    【讨论】:

      【解决方案4】:

      这会起作用,产生 436 种组合:

      import itertools as itls
      
      colors      = ["blue", "yellow", "green", "black", "magenta"]
      numbers     = [1,2,3,4,5,6,7,8]
      material    = ["beton", "wood", "stone"]
      names       = ["Susi", "Klara", "Claire", "Moni"]
      
      my_lists    = [colors, numbers, material, names]
      
      my_combos = [(x,y,z) for (lst_1,lst_2,lst_3) in itls.combinations(my_lists,3) 
                                   for (x,y,z) in itls.product(lst_1, lst_2, lst_3) ]
      
      # print (my_combos)
      print (len(my_combos))
      

      说明:

      所需的结果被构造为一个列表,并分配给my_combos

      列表是使用具有嵌套双迭代的列表推导式构造的。

      在嵌套的双重迭代中:

      1. 外部 for 循环 for (lst_1,lst_2,lst_3) in itls.combinations(my_lists,3) 迭代所有可能的列表组合,一次获取 3 个列表。
      2. 内部 for 循环 for (x,y,z) in itls.product(lst_1, lst_2, lst_3) 迭代 lst_1lst_2lst_3 的笛卡尔积(这些 lst_1lst_2lst_3 为外部的每次迭代定义for 循环)

      验证结果中没有重复的代码:

      # Code to verify that there are no duplicates.
      from collections import Counter
      for x, count_x in counts.items():
          if (count_x > 1): # if duplicate
              print ("Duplicate item ({}) occurs {} times".format(x, count_x))
      

      【讨论】:

      • 非常复杂的解决方案。如果您解释所有步骤,我会投票赞成。
      • @MykolaZotko,添加了解释。
      • 我认为你会得到像 [blue, 1, beton][beton, 1, blue] 这样的重复项。你得到排列。
      • @MykolaZotko,只有在使用permutations 而不是combinations 时,才会出现您提到的重复项。无论如何,手动计算确认 436 是预期的正确组合数,这也是它给出的结果。
      • 我需要的是列表中所有项目的组合,无论列表的顺序如何。前提是:4个列表中必须有3个,并且不能重复。 #fountainhead:这里有一些重复 #Mykola Zotko:没错,我的示例中没有出现名称只是巧合
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-12
      • 2016-10-13
      • 2011-02-27
      • 2022-01-21
      相关资源
      最近更新 更多