Jos*_*shD 19 python permutation
在Python中,使用itertools模块生成列表的所有排列非常简单.我有一种情况,我使用的列表只有两个字符(即'1122').我想生成所有独特的排列.
对于字符串'1122',有6个唯一的排列(1122,1212,1221等),但itertools.permutations将产生24个项目.仅记录唯一排列很简单,但是由于考虑了所有720个项目,因此收集它们所需的时间要长得多.
是否有一个函数或模块在生成排列时会考虑重复的元素,所以我不必自己编写?
hug*_*own 18
这个网页看起来很有前景.
def next_permutation(seq, pred=cmp):
"""Like C++ std::next_permutation() but implemented as
generator. Yields copies of seq."""
def reverse(seq, start, end):
# seq = seq[:start] + reversed(seq[start:end]) + \
# seq[end:]
end -= 1
if end <= start:
return
while True:
seq[start], seq[end] = seq[end], seq[start]
if start == end or start+1 == end:
return
start += 1
end -= 1
if not seq:
raise StopIteration
try:
seq[0]
except TypeError:
raise TypeError("seq must allow random access.")
first = 0
last = len(seq)
seq = seq[:]
# Yield input sequence as the STL version is often
# used inside do {} while.
yield seq[:]
if last == 1:
raise StopIteration
while True:
next = last - 1
while True:
# Step 1.
next1 = next
next -= 1
if pred(seq[next], seq[next1]) < 0:
# Step 2.
mid = last - 1
while not (pred(seq[next], seq[mid]) < 0):
mid -= 1
seq[next], seq[mid] = seq[mid], seq[next]
# Step 3.
reverse(seq, next1, last)
# Change to yield references to get rid of
# (at worst) |seq|! copy operations.
yield seq[:]
break
if next == first:
raise StopIteration
raise StopIteration
>>> for p in next_permutation([int(c) for c in "111222"]):
... print p
...
[1, 1, 1, 2, 2, 2]
[1, 1, 2, 1, 2, 2]
[1, 1, 2, 2, 1, 2]
[1, 1, 2, 2, 2, 1]
[1, 2, 1, 1, 2, 2]
[1, 2, 1, 2, 1, 2]
[1, 2, 1, 2, 2, 1]
[1, 2, 2, 1, 1, 2]
[1, 2, 2, 1, 2, 1]
[1, 2, 2, 2, 1, 1]
[2, 1, 1, 1, 2, 2]
[2, 1, 1, 2, 1, 2]
[2, 1, 1, 2, 2, 1]
[2, 1, 2, 1, 1, 2]
[2, 1, 2, 1, 2, 1]
[2, 1, 2, 2, 1, 1]
[2, 2, 1, 1, 1, 2]
[2, 2, 1, 1, 2, 1]
[2, 2, 1, 2, 1, 1]
[2, 2, 2, 1, 1, 1]
>>>
Run Code Online (Sandbox Code Playgroud)
2017年8月12日
七年后,这是一个更好的算法(更好的清晰度):
from itertools import permutations
def unique_perms(series):
return {"".join(p) for p in permutations(series)}
print(sorted(unique_perms('1122')))
Run Code Online (Sandbox Code Playgroud)
more-itertools.distinct_permutations(iterable)产生iterable 中元素的连续不同排列。
等价于
set(permutations(iterable)),但不会生成和丢弃重复项。对于更大的输入序列,这更有效。
from more_itertools import distinct_permutations
for p in distinct_permutations('1122'):
print(''.join(p))
# 2211
# 2121
# 1221
# 2112
# 1212
# 1122
Run Code Online (Sandbox Code Playgroud)
安装:
pip install more-itertools
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5036 次 |
| 最近记录: |