2015-10-26 128 views
1

我有一个列表的列表,我们可以认为它是3个球的3个球。itertools和从分区集合中选择

mylist= [ 
      ['HIGH_1', 'MED_1', 'LOW_1'], 
      ['HIGH_2', 'MED_2', 'LOW_2'], 
      ['HIGH_3', 'MED_3', 'LOW_3'] 
     ] 

我只允许从每个瓮中选择一个球。 我想获得1球,2球和3球的所有组合。在列表中回答。

为了实现这一点,我在每个

mylist= [ 
      [None, 'HIGH_1', 'MED_1', 'LOW_1'], 
      [None, 'HIGH_2', 'MED_2', 'LOW_2'], 
      [None, 'HIGH_3', 'MED_3', 'LOW_3'] 
      ] 

放置一个假元件(无)现在以下使用itertools的和过滤器获取我所需的解决方案。

combos = [] 
for l in itertools.product(*mylist): 
    combos.append(filter(lambda a: a is not None, l)) 

combos.remove(()) # remove the empty element 
print [list(elem) for elem in combos] 


[['HIGH_3'], ['MED_3'], ['LOW_3'], ... , ['MED_2', 'HIGH_3'], ['MED_2', 'MED_3'], ['MED_1', 'HIGH_3'], ..., ['LOW_1', 'LOW_2', 'MED_3'], ['LOW_1', 'LOW_2', 'LOW_3']] 

其中产生63个元素。

9(单元素)+ 27(两个元素)+ 27(三要素)= 63

添加在假和后过滤不觉得自己做到这一点的最好办法。

有没有办法避免这两个看似多余的步骤?

+3

那么你写了什么,究竟是什么问题呢? – jonrsharpe

+0

你有*“更好”*的标准吗? – jonrsharpe

回答

1

您可以用下面的发电机

def combos(data): 
    for i in xrange(1, len(data) + 1): 
     for item in itertools.combinations(data, i): 
      for j in itertools.product(*item): 
       yield j 

也许最Python的解决方案,我能想到的做到这一点。

0

当您只附加非空项目时,您不需要remove()。您也可以通过在过滤器之后立即将项目转换为列表来跳过最后的列表理解。

import itertools 
import pprint 

mylist= [ 
      [None, 'HIGH_1', 'MED_1', 'LOW_1'], 
      [None, 'HIGH_2', 'MED_2', 'LOW_2'], 
      [None, 'HIGH_3', 'MED_3', 'LOW_3'] 
      ] 
combos = [] 
for item in itertools.product(*mylist): 
    combo = list(filter(lambda a: a is not None, item)) 
    if combo: 
     combos.append(combo) 

pprint.pprint(combos) 

UPDATE

手动插入None是不是很好。添加一条线,这是否在列表的理解:

import itertools 
import pprint 

mylist= [ 
      ['HIGH_1', 'MED_1', 'LOW_1'], 
      ['HIGH_2', 'MED_2', 'LOW_2'], 
      ['HIGH_3', 'MED_3', 'LOW_3'] 
      ] 

mylist_with_nones = [[None] + item for item in mylist] 
combos = [] 
for item in itertools.product(*mylist_with_nones): 
    combo = list(filter(lambda a: a is not None, item)) 
    if combo: 
     combos.append(combo) 

pprint.pprint(combos) 
+0

感谢Mike,这有帮助,我希望不必将三个None值添加到我的数组中。看看第一个mylist对象。你可以用这个对象得到想要的结果而不必在每个数组中添加一个None。 – Dickster

+0

您不必手动添加'None'条目。我更新了我的答案,并添加了一条为您提供帮助的线路。 –