Python 列表的排列
我有这样一份清单:Python 列表的排列,python,Python,我有这样一份清单: l = [['a', 'b', 'c'], ['a', 'b'], ['g', 'h', 'r', 'w']] 我想从每个列表中选择一个元素,并将它们组合成一个字符串 例如:“aag”,“aah”,“aar”,“aaw”,“abg”,“abh” 但是,在程序运行之前,列表l的长度和每个内部列表的长度都是未知的。那么,我怎样才能真正想要我想要的呢?拿一个例子,用itertools.product(*l)来代替。使用itertools.product很容易 >>&g
l = [['a', 'b', 'c'], ['a', 'b'], ['g', 'h', 'r', 'w']]
我想从每个列表中选择一个元素,并将它们组合成一个字符串
例如:“aag”,“aah”,“aar”,“aaw”,“abg”,“abh”
但是,在程序运行之前,列表l的长度和每个内部列表的长度都是未知的。那么,我怎样才能真正想要我想要的呢?拿一个例子,用
itertools.product(*l)
来代替。使用itertools.product很容易
>>> import itertools
>>> list(itertools.product("abc", "ab", "ghrw"))
[('a', 'a', 'g'), ('a', 'a', 'h'), ('a', 'a', 'r'), ('a', 'a', 'w'), ('a', 'b', 'g'), ('a', 'b', 'h'), ('a', 'b', 'r'), ('a', 'b', 'w'), ('b', 'a', 'g'), ('b', 'a', 'h'), ('b', 'a', 'r'), ('b', 'a', 'w'), ('b', 'b', 'g'), ('b', 'b', 'h'), ('b', 'b', 'r'), ('b', 'b', 'w'), ('c', 'a', 'g'), ('c', 'a', 'h'), ('c', 'a', 'r'), ('c', 'a', 'w'), ('c', 'b', 'g'), ('c', 'b', 'h'), ('c', 'b', 'r'), ('c', 'b', 'w')]
如果有人对该算法感兴趣,这里有一个非常简单的方法来使用递归查找组合:
l = [['a', 'b', 'c'], ['a', 'b'], ['g', 'h', 'r', 'w']]
def permu(lists, prefix=''):
if not lists:
print prefix
return
first = lists[0]
rest = lists[1:]
for letter in first:
permu(rest, prefix + letter)
permu(l)
给你
reduce(lambda a,b: [i+j for i in a for j in b], l)
OUT: ['aag', 'aah', 'aar', 'aaw', 'abg', 'abh', 'abr', 'abw', 'bag', 'bah', 'bar', 'baw', 'bbg', 'bbh', 'bbr', 'bbw', 'cag', 'cah', 'car', 'caw', 'cbg', 'cbh', 'cbr', 'cbw']
如果您希望重用/重新生成:
def opOnCombos(a,b, op=operator.add):
return [op(i,j) for i in a for j in b]
def f(x):
return lambda a,b: opOnCombo(a,b,x)
reduce(opOnCombos, l) //same as before
reduce(f(operator.mul), l)) //multiply combos of several integer list
使用递归
def permutenew(l):
if len(l)==1:
return l[0]
else:
lnew=[]
for a in l[0]:
for b in permutenew(l[1:]):
lnew.append(a+b)
return lnew
l = [['a', 'b', 'c'], ['a', 'b'], ['g', 'h', 'r', 'w']]
print permutenew(l)
小猪背着小猪。以下内容将创建一个列表,而不是打印。请注意,这可能非常缓慢,因为它需要大量内存来存储值
from __future__ import print_function
import itertools # Not actually used in the code below
def permu(lists):
def fn(lists, group=[], result=[]):
if not lists:
result.append(group)
return
first, rest = lists[0], lists[1:]
for letter in first:
fn(rest, group + [letter], result)
result = []
fn(lists, result=result)
return result
if __name__ == '__main__':
ll = [ [[1, 2, 3], [5, 10], [42]],
[['a', 'b', 'c'], ['a', 'b'], ['g', 'h', 'r', 'w']] ]
nth = lambda i: 'Permutation #{0}:\n{1}'.format(i, '-'*16)
# Note: permu(list) can be replaced with itertools.product(*l)
[[print(p) for p in [nth(i)]+permu(l)+['\n']] for i,l in enumerate(ll)]
结果
Permutation #0:
----------------
[1, 5, 42]
[1, 10, 42]
[2, 5, 42]
[2, 10, 42]
[3, 5, 42]
[3, 10, 42]
Permutation #1:
----------------
['a', 'a', 'g']
['a', 'a', 'h']
['a', 'a', 'r']
['a', 'a', 'w']
['a', 'b', 'g']
['a', 'b', 'h']
['a', 'b', 'r']
['a', 'b', 'w']
['b', 'a', 'g']
['b', 'a', 'h']
['b', 'a', 'r']
['b', 'a', 'w']
['b', 'b', 'g']
['b', 'b', 'h']
['b', 'b', 'r']
['b', 'b', 'w']
['c', 'a', 'g']
['c', 'a', 'h']
['c', 'a', 'r']
['c', 'a', 'w']
['c', 'b', 'g']
['c', 'b', 'h']
['c', 'b', 'r']
['c', 'b', 'w']
以下是对以下内容的等效替代: 此函数相当于以下代码,但实际实现不会在内存中建立中间结果:
def product(*args, **kwds):
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)
你想要所有的组合,还是一个随机的组合?把它拼出来:
[''.join(s)for s in itertools.product(*l)]
@wong2你是说我希望很棒?幻想有点不同:)你能解释一下*运算符吗?我觉得我从来没有100%得到过it@jon_darkstar:它将序列解压为位置参数。@Jon:*
运算符将序列中的元素替换为调用中的参数;如果l==[1,2,3]
则f(*l)
与f(1,2,3)
相同;因此,astring.replace(*“ab”)
是调用astring.replace(“a”、“b”)
的一种愚蠢方式。