python中如何生成列表_如何在Python中生成列表的所有排列

如何在Python中生成列表的所有排列,而与列表中元素的类型无关?

例如:

permutations([])

[]

permutations([1])

[1]

permutations([1, 2])

[1, 2]

[2, 1]

permutations([1, 2, 3])

[1, 2, 3]

[1, 3, 2]

[2, 1, 3]

[2, 3, 1]

[3, 1, 2]

[3, 2, 1]

#1楼

此解决方案实现了一个生成器,以避免将所有排列保留在内存中:

def permutations (orig_list):

if not isinstance(orig_list, list):

orig_list = list(orig_list)

yield orig_list

if len(orig_list) == 1:

return

for n in sorted(orig_list):

new_list = orig_list[:]

pos = new_list.index(n)

del(new_list[pos])

new_list.insert(0, n)

for resto in permutations(new_list[1:]):

if new_list[:1] + resto <> orig_list:

yield new_list[:1] + resto

#2楼

从Python 2.6开始 (如果您使用的是Python 3),您可以使用一个标准库工具: itertools.permutations 。

import itertools

list(itertools.permutations([1, 2, 3]))

如果您出于某种原因使用旧版本的Python(<2.6) ,或者只是想知道它的工作原理,那么这是一种不错的方法,摘自http://code.activestate.com/recipes/252178/ :

def all_perms(elements):

if len(elements) <=1:

yield elements

else:

for perm in all_perms(elements[1:]):

for i in range(len(elements)):

# nb elements[0:1] works in both string and list contexts

yield perm[:i] + elements[0:1] + perm[i:]

itertools.permutations的文档中列出了几种其他方法。 这是一个:

def permutations(iterable, r=None):

# permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC

# permutations(range(3)) --> 012 021 102 120 201 210

pool = tuple(iterable)

n = len(pool)

r = n if r is None else r

if r > n:

return

indices = range(n)

cycles = range(n, n-r, -1)

yield tuple(pool[i] for i in indices[:r])

while n:

for i in reversed(range(r)):

cycles[i] -= 1

if cycles[i] == 0:

indices[i:] = indices[i+1:] + indices[i:i+1]

cycles[i] = n - i

else:

j = cycles[i]

indices[i], indices[-j] = indices[-j], indices[i]

yield tuple(pool[i] for i in indices[:r])

break

else:

return

另一个基于itertools.product :

def permutations(iterable, r=None):

pool = tuple(iterable)

n = len(pool)

r = n if r is None else r

for indices in product(range(n), repeat=r):

if len(set(indices)) == r:

yield tuple(pool[i] for i in indices)

#3楼

import itertools

itertools.permutations([1,2,3])

(作为生成器返回。使用list(permutations(l))作为列表返回。)

#4楼

正如tzwenn的回答,确实可以迭代每个排列的第一个元素。 我更喜欢这样写这个解决方案:

def all_perms(elements):

if len(elements) <= 1:

yield elements # Only permutation possible = no permutation

else:

# Iteration over the first element in the result permutation:

for (index, first_elmt) in enumerate(elements):

other_elmts = elements[:index]+elements[index+1:]

for permutation in all_perms(other_elmts):

yield [first_elmt] + permutation

该解决方案的速度提高了约30%,这显然归功于递归以len(elements) <= 1而不是0 。 就像Riccardo Reyes的解决方案一样,它使用生成器函数(通过yield ),因此还可以提高内存效率。

#5楼

以下代码是给定列表的就地排列,实现为生成器。 由于仅返回对列表的引用,因此不应在生成器外部修改列表。 该解决方案是非递归的,因此使用低内存。 输入列表中元素的多个副本也可以很好地工作。

def permute_in_place(a):

a.sort()

yield list(a)

if len(a) <= 1:

return

first = 0

last = len(a)

while 1:

i = last - 1

while 1:

i = i - 1

if a[i] < a[i+1]:

j = last - 1

while not (a[i] < a[j]):

j = j - 1

a[i], a[j] = a[j], a[i] # swap the values

r = a[i+1:last]

r.reverse()

a[i+1:last] = r

yield list(a)

break

if i == first:

a.reverse()

return

if __name__ == '__main__':

for n in range(5):

for a in permute_in_place(range(1, n+1)):

print a

print

for a in permute_in_place([0, 0, 1, 1, 1]):

print a

print

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值