All combinations of a list of lists
我基本上是在寻找一个python版本的>
给定一个列表列表,我需要一个新列表,它列出了列表之间所有可能的项目组合。
1 | [[1,2,3],[4,5,6],[7,8,9,10]] -> [[1,4,7],[1,4,8],...,[3,6,10]] |
列表的数量是未知的,所以我需要一些适用于所有情况的东西。 优点加分!
你需要
1 2 3 4 | >>> import itertools >>> a = [[1,2,3],[4,5,6],[7,8,9,10]] >>> list(itertools.product(*a)) [(1, 4, 7), (1, 4, 8), (1, 4, 9), (1, 4, 10), (1, 5, 7), (1, 5, 8), (1, 5, 9), (1, 5, 10), (1, 6, 7), (1, 6, 8), (1, 6, 9), (1, 6, 10), (2, 4, 7), (2, 4, 8), (2, 4, 9), (2, 4, 10), (2, 5, 7), (2, 5, 8), (2, 5, 9), (2, 5, 10), (2, 6, 7), (2, 6, 8), (2, 6, 9), (2, 6, 10), (3, 4, 7), (3, 4, 8), (3, 4, 9), (3, 4, 10), (3, 5, 7), (3, 5, 8), (3, 5, 9), (3, 5, 10), (3, 6, 7), (3, 6, 8), (3, 6, 9), (3, 6, 10)] |
最优雅的解决方案是在python 2.6中使用itertools.product。
如果您不使用Python 2.6,则itertools.product的文档实际上显示了一个等效的函数来以"手动"的方式执行产品:
1 2 3 4 5 6 7 8 9 | def product(*args, **kwds): # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 pools = map(tuple, args) * kwds.get('repeat', 1) result = [[]] for pool in pools: result = [x+[y] for x in result for y in pool] for prod in result: yield tuple(prod) |
1 2 3 | listOLists = [[1,2,3],[4,5,6],[7,8,9,10]] for list in itertools.product(*listOLists): print list; |
我希望你发现它和我第一次遇到它时一样优雅。
此任务的直接递归没有错,如果您需要一个适用于字符串的版本,这可能符合您的需求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | combinations = [] def combine(terms, accum): last = (len(terms) == 1) n = len(terms[0]) for i in range(n): item = accum + terms[0][i] if last: combinations.append(item) else: combine(terms[1:], item) >>> a = [['ab','cd','ef'],['12','34','56']] >>> combine(a, '') >>> print(combinations) ['ab12', 'ab34', 'ab56', 'cd12', 'cd34', 'cd56', 'ef12', 'ef34', 'ef56'] |
Numpy可以做到:
1 2 3 4 | >>> import numpy >>> a = [[1,2,3],[4,5,6],[7,8,9,10]] >>> [list(x) for x in numpy.array(numpy.meshgrid(*a)).T.reshape(-1,len(a))] [[ 1, 4, 7], [1, 5, 7], [1, 6, 7], ....] |
可以使用base python。 代码需要一个函数来展平列表列表:
1 2 3 4 5 6 | def flatten(B): # function needed for code below; A = [] for i in B: if type(i) == list: A.extend(i) else: A.append(i) return A |
然后一个人可以运行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | L = [[1,2,3],[4,5,6],[7,8,9,10]] outlist =[]; templist =[[]] for sublist in L: outlist = templist; templist = [[]] for sitem in sublist: for oitem in outlist: newitem = [oitem] if newitem == [[]]: newitem = [sitem] else: newitem = [newitem[0], sitem] templist.append(flatten(newitem)) outlist = list(filter(lambda x: len(x)==len(L), templist)) # remove some partial lists that also creep in; print(outlist) |
输出:
1 2 3 4 5 6 7 8 9 10 11 12 | [[1, 4, 7], [2, 4, 7], [3, 4, 7], [1, 5, 7], [2, 5, 7], [3, 5, 7], [1, 6, 7], [2, 6, 7], [3, 6, 7], [1, 4, 8], [2, 4, 8], [3, 4, 8], [1, 5, 8], [2, 5, 8], [3, 5, 8], [1, 6, 8], [2, 6, 8], [3, 6, 8], [1, 4, 9], [2, 4, 9], [3, 4, 9], [1, 5, 9], [2, 5, 9], [3, 5, 9], [1, 6, 9], [2, 6, 9], [3, 6, 9], [1, 4, 10], [2, 4, 10], [3, 4, 10], [1, 5, 10], [2, 5, 10], [3, 5, 10], [1, 6, 10], [2, 6, 10], [3, 6, 10]] |
1 2 3 | from itertools import product list_vals = [['Brand Acronym:CBIQ', 'Brand Acronym :KMEFIC'],['Brand Country:DXB','Brand Country:BH']] list(product(*list_vals)) |
输出:
[('Brand Acronym:CBIQ', 'Brand Country :DXB'),
('Brand Acronym:CBIQ', 'Brand Country:BH'),
('Brand Acronym :KMEFIC', 'Brand Country :DXB'),
('Brand Acronym :KMEFIC', 'Brand Country:BH')]