如何找到最小的组合集[python> itertools> product]:代码审查

时间:2017-07-20 07:38:22

标签: python performance python-3.x iterator memory-efficient

如何在不计算itertools.product函数返回的所有可能组合的情况下改进此代码。 是否有其他解决方案可以有效地完成。

这就是我的尝试:

import itertools

mylist = [[1,2,3],[1,3,4],[1,2,3]]

k = [set(i) for i in list(itertools.product(*mylist))]
k = sorted(k)
D_all = list(k for k, _ in itertools.groupby(k))
D_all.sort(key=len)


# Finding and displaying the minimum order-split combination
l = len(D_all[0])
print("Minimum number of Distributor Combination found is: {}".format(l))
print("The Possible combinations of {} are: ".format(l))
D_best = []
c = 0
for n,i in enumerate(D_all):

    if len(i)<=l:
        c +=1
        print("{}:{}".format(c,i))
        D_best.append(i)
        if len(i)>l+1: break
  

输出:

Minimum number of Distributor Combination found is: 1
The Possible combinations of 1 are: 
1:{'1'}
2:{'3'}

1 个答案:

答案 0 :(得分:1)

我相信我拥有它。您可以在确定性方式中利用itertools.product yields tuple的事实;你事先知道什么单身人士会被收获。你只需要计算何时会发生这种情况。

from itertools import islice, product
from functools import reduce

mylist = [[1, 2, 3], [1, 3, 4], [1, 2, 3]]

stop_cond = (len(mylist[0]) - 1) * reduce(lambda x, y: len(x) * len(y), mylist[1:])
pivot = mylist[0][-1]
stop_cond += reduce(lambda x, y: (x.index(pivot) + 1) * (y.index(pivot) + 1), mylist[1:])

k = [set(item) for item in islice(product(*mylist), stop_cond)]
print(k)  #[{1}, {1, 2}, {1, 3}, {1, 3}, {1, 2, 3}, {1, 3}, {1, 4}, {1, 2, 4}, {1, 3, 4}, {1, 2}, {1, 2}, {1, 2, 3}, {1, 2, 3}, {2, 3}, {2, 3}, {1, 2, 4}, {2, 4}, {2, 3, 4}, {1, 3}, {1, 2, 3}, {1, 3}, {1, 3}, {2, 3}, {3}]

在这种情况下,最后一个单例将是{3},因为3出现在第一个list的最后一个位置(我在代码中称为pivot)。要获得它的单身人士,你必须先获得所有其他人,并且每个人需要3 * 3的收益。那就是9 + 9 = 18.现在最后,您只需要在剩余的列表中找到它的索引(在基于1索引的系统中)并将它们相乘。