[英]permutations with recursion in python
I have a task to make a code that takes a list of undefined number and print all permutations with the first constant using recursion and here is a code I wrote but I don't know where is the problem我的任务是编写一个代码,该代码采用未定义数字列表并使用递归打印带有第一个常量的所有排列,这是我编写的代码,但我不知道问题出在哪里
portnames = ["PAN", "AMS", "CAS", "NYC", "HEL"]
def permutations(route, ports):
for items in ports:
route.append(ports)
ports = ports[:items]+ports[items+1:]
permutations(route, ports)
print(' '.join([portnames[i] for i in route]))
permutations([0], list(range(1, len(portnames))))
note: the function must contain注意:function 必须包含
We can write permutations(t)
of any iterable t
using inductive reasoning -我们可以使用归纳推理编写任何可迭代
t
的permutations(t)
-
t
is empty, yield the empty permutation, ()
t
为空,则产生空排列, ()
t
has at least one element. t
至少有一个元素。 For all p
of the recursive sub-problem permutations(t[1:])
, for all i
of inserts(p, t[0])
, yield i
p
的递归子问题permutations(t[1:])
,对于所有i
的inserts(p, t[0])
,产生i
def permutations(t):
if not t:
yield () # 1. empty t
else:
for p in permutations(t[1:]): # 2. at least one element
for i in inserts(p, t[0]):
yield i
Where inserts(t, x)
can be written using inductive reasoning as well -其中
inserts(t, x)
也可以使用归纳推理来编写 -
t
is empty, yield the final insert, (x)
t
为空,则产生最终插入, (x)
t
has at least one element. t
至少有一个元素。 yield x
prepended to t
and for all i
of the recursive sub-problem inserts(t[1:], x)
yield t[0]
prepended to i
x
附加到t
并且对于所有i
递归子问题inserts(t[1:], x)
yield t[0]
附加到i
def inserts(t, x):
if not t:
yield (x,) # 1. empty t
else:
yield (x, *t) # 2. at least one element
for i in inserts(t[1:], x):
yield (t[0], *i)
t = ("🔴","🟢","🔵","🟡")
for p in permutations(t):
print("".join(p))
🔴🟢🔵🟡
🟢🔴🔵🟡
🟢🔵🔴🟡
🟢🔵🟡🔴
🔴🔵🟢🟡
🔵🔴🟢🟡
🔵🟢🔴🟡
🔵🟢🟡🔴
🔴🔵🟡🟢
🔵🔴🟡🟢
🔵🟡🔴🟢
🔵🟡🟢🔴
🔴🟢🟡🔵
🟢🔴🟡🔵
🟢🟡🔴🔵
🟢🟡🔵🔴
🔴🟡🟢🔵
🟡🔴🟢🔵
🟡🟢🔴🔵
🟡🟢🔵🔴
🔴🟡🔵🟢
🟡🔴🔵🟢
🟡🔵🔴🟢
🟡🔵🟢🔴
Python has strong support for generators and offers delegation using yield from..
. Python 对生成器有强大的支持,并使用
yield from..
提供委托。 We can simplify the above definitions while maintaining the exact same behaviour -我们可以简化上述定义,同时保持完全相同的行为 -
def permutations(t):
if not t:
yield ()
else:
for p in permutations(t[1:]):
yield from inserts(p, t[0]) # <-
def inserts(t, x):
if not t:
yield (x,)
else:
yield (x, *t)
yield from map(lambda r: (t[0], *r), inserts(t[1:], x)) # <-
Generators are a good fit for combinatorics because working with them is natural and straightforward -生成器非常适合组合数学,因为使用它们是自然而直接的 -
# find all permutations where red is left of green
for p in permutations(t):
if p.index("🔴") < p.index("🟢"):
print("".join(p))
🔴🟢🔵🟡
🔴🔵🟢🟡
🔵🔴🟢🟡
🔴🔵🟡🟢
🔵🔴🟡🟢
🔵🟡🔴🟢
🔴🟢🟡🔵
🔴🟡🟢🔵
🟡🔴🟢🔵
🔴🟡🔵🟢
🟡🔴🔵🟢
🟡🔵🔴🟢
# find all permutations where blue and yellow are adjacent
for p in permutations(t):
if abs(p.index("🔵") - p.index("🟡")) == 1:
print("".join(p))
🔴🟢🔵🟡
🟢🔴🔵🟡
🟢🔵🟡🔴
🔴🔵🟡🟢
🔵🟡🔴🟢
🔵🟡🟢🔴
🔴🟢🟡🔵
🟢🔴🟡🔵
🟢🟡🔵🔴
🔴🟡🔵🟢
🟡🔵🔴🟢
🟡🔵🟢🔴
Additionally generators can be paused/stopped at any time, allowing us to skip potentially millions of computations for significantly large problems -此外,生成器可以随时暂停/停止,允许我们跳过潜在的数百万次计算以解决非常大的问题 -
# which permutation is in rainbow order?
for (n, p) in enumerate(permutations(t)):
if p == ("🔴", "🟡", "🟢", "🔵"):
print(f"permutation {n} is in rainbow order, {p}")
break # <- stops generating additional permutations
permutation 16 is in rainbow order, ('🔴', '🟡', '🟢', '🔵')
We use permutations
with your portnames
data now -我们现在对您的
portnames
数据使用permutations
-
portnames = ["PAN", "AMS", "CAS", "NYC", "HEL"]
for x in permutations(portnames):
print(x)
('PAN', 'AMS', 'CAS', 'NYC', 'HEL')
('AMS', 'PAN', 'CAS', 'NYC', 'HEL')
('AMS', 'CAS', 'PAN', 'NYC', 'HEL')
('AMS', 'CAS', 'NYC', 'PAN', 'HEL')
('AMS', 'CAS', 'NYC', 'HEL', 'PAN')
('PAN', 'CAS', 'AMS', 'NYC', 'HEL')
('CAS', 'PAN', 'AMS', 'NYC', 'HEL')
('CAS', 'AMS', 'PAN', 'NYC', 'HEL')
('CAS', 'AMS', 'NYC', 'PAN', 'HEL')
('CAS', 'AMS', 'NYC', 'HEL', 'PAN')
('PAN', 'CAS', 'NYC', 'AMS', 'HEL')
('CAS', 'PAN', 'NYC', 'AMS', 'HEL')
('CAS', 'NYC', 'PAN', 'AMS', 'HEL')
('CAS', 'NYC', 'AMS', 'PAN', 'HEL')
('CAS', 'NYC', 'AMS', 'HEL', 'PAN')
('PAN', 'CAS', 'NYC', 'HEL', 'AMS')
('CAS', 'PAN', 'NYC', 'HEL', 'AMS')
('CAS', 'NYC', 'PAN', 'HEL', 'AMS')
('CAS', 'NYC', 'HEL', 'PAN', 'AMS')
('CAS', 'NYC', 'HEL', 'AMS', 'PAN')
('PAN', 'AMS', 'NYC', 'CAS', 'HEL')
('AMS', 'PAN', 'NYC', 'CAS', 'HEL')
('AMS', 'NYC', 'PAN', 'CAS', 'HEL')
('AMS', 'NYC', 'CAS', 'PAN', 'HEL')
('AMS', 'NYC', 'CAS', 'HEL', 'PAN')
('PAN', 'NYC', 'AMS', 'CAS', 'HEL')
('NYC', 'PAN', 'AMS', 'CAS', 'HEL')
('NYC', 'AMS', 'PAN', 'CAS', 'HEL')
('NYC', 'AMS', 'CAS', 'PAN', 'HEL')
('NYC', 'AMS', 'CAS', 'HEL', 'PAN')
('PAN', 'NYC', 'CAS', 'AMS', 'HEL')
('NYC', 'PAN', 'CAS', 'AMS', 'HEL')
('NYC', 'CAS', 'PAN', 'AMS', 'HEL')
('NYC', 'CAS', 'AMS', 'PAN', 'HEL')
('NYC', 'CAS', 'AMS', 'HEL', 'PAN')
('PAN', 'NYC', 'CAS', 'HEL', 'AMS')
('NYC', 'PAN', 'CAS', 'HEL', 'AMS')
('NYC', 'CAS', 'PAN', 'HEL', 'AMS')
('NYC', 'CAS', 'HEL', 'PAN', 'AMS')
('NYC', 'CAS', 'HEL', 'AMS', 'PAN')
('PAN', 'AMS', 'NYC', 'HEL', 'CAS')
('AMS', 'PAN', 'NYC', 'HEL', 'CAS')
('AMS', 'NYC', 'PAN', 'HEL', 'CAS')
('AMS', 'NYC', 'HEL', 'PAN', 'CAS')
('AMS', 'NYC', 'HEL', 'CAS', 'PAN')
('PAN', 'NYC', 'AMS', 'HEL', 'CAS')
('NYC', 'PAN', 'AMS', 'HEL', 'CAS')
('NYC', 'AMS', 'PAN', 'HEL', 'CAS')
('NYC', 'AMS', 'HEL', 'PAN', 'CAS')
('NYC', 'AMS', 'HEL', 'CAS', 'PAN')
('PAN', 'NYC', 'HEL', 'AMS', 'CAS')
('NYC', 'PAN', 'HEL', 'AMS', 'CAS')
('NYC', 'HEL', 'PAN', 'AMS', 'CAS')
('NYC', 'HEL', 'AMS', 'PAN', 'CAS')
('NYC', 'HEL', 'AMS', 'CAS', 'PAN')
('PAN', 'NYC', 'HEL', 'CAS', 'AMS')
('NYC', 'PAN', 'HEL', 'CAS', 'AMS')
('NYC', 'HEL', 'PAN', 'CAS', 'AMS')
('NYC', 'HEL', 'CAS', 'PAN', 'AMS')
('NYC', 'HEL', 'CAS', 'AMS', 'PAN')
('PAN', 'AMS', 'CAS', 'HEL', 'NYC')
('AMS', 'PAN', 'CAS', 'HEL', 'NYC')
('AMS', 'CAS', 'PAN', 'HEL', 'NYC')
('AMS', 'CAS', 'HEL', 'PAN', 'NYC')
('AMS', 'CAS', 'HEL', 'NYC', 'PAN')
('PAN', 'CAS', 'AMS', 'HEL', 'NYC')
('CAS', 'PAN', 'AMS', 'HEL', 'NYC')
('CAS', 'AMS', 'PAN', 'HEL', 'NYC')
('CAS', 'AMS', 'HEL', 'PAN', 'NYC')
('CAS', 'AMS', 'HEL', 'NYC', 'PAN')
('PAN', 'CAS', 'HEL', 'AMS', 'NYC')
('CAS', 'PAN', 'HEL', 'AMS', 'NYC')
('CAS', 'HEL', 'PAN', 'AMS', 'NYC')
('CAS', 'HEL', 'AMS', 'PAN', 'NYC')
('CAS', 'HEL', 'AMS', 'NYC', 'PAN')
('PAN', 'CAS', 'HEL', 'NYC', 'AMS')
('CAS', 'PAN', 'HEL', 'NYC', 'AMS')
('CAS', 'HEL', 'PAN', 'NYC', 'AMS')
('CAS', 'HEL', 'NYC', 'PAN', 'AMS')
('CAS', 'HEL', 'NYC', 'AMS', 'PAN')
('PAN', 'AMS', 'HEL', 'CAS', 'NYC')
('AMS', 'PAN', 'HEL', 'CAS', 'NYC')
('AMS', 'HEL', 'PAN', 'CAS', 'NYC')
('AMS', 'HEL', 'CAS', 'PAN', 'NYC')
('AMS', 'HEL', 'CAS', 'NYC', 'PAN')
('PAN', 'HEL', 'AMS', 'CAS', 'NYC')
('HEL', 'PAN', 'AMS', 'CAS', 'NYC')
('HEL', 'AMS', 'PAN', 'CAS', 'NYC')
('HEL', 'AMS', 'CAS', 'PAN', 'NYC')
('HEL', 'AMS', 'CAS', 'NYC', 'PAN')
('PAN', 'HEL', 'CAS', 'AMS', 'NYC')
('HEL', 'PAN', 'CAS', 'AMS', 'NYC')
('HEL', 'CAS', 'PAN', 'AMS', 'NYC')
('HEL', 'CAS', 'AMS', 'PAN', 'NYC')
('HEL', 'CAS', 'AMS', 'NYC', 'PAN')
('PAN', 'HEL', 'CAS', 'NYC', 'AMS')
('HEL', 'PAN', 'CAS', 'NYC', 'AMS')
('HEL', 'CAS', 'PAN', 'NYC', 'AMS')
('HEL', 'CAS', 'NYC', 'PAN', 'AMS')
('HEL', 'CAS', 'NYC', 'AMS', 'PAN')
('PAN', 'AMS', 'HEL', 'NYC', 'CAS')
('AMS', 'PAN', 'HEL', 'NYC', 'CAS')
('AMS', 'HEL', 'PAN', 'NYC', 'CAS')
('AMS', 'HEL', 'NYC', 'PAN', 'CAS')
('AMS', 'HEL', 'NYC', 'CAS', 'PAN')
('PAN', 'HEL', 'AMS', 'NYC', 'CAS')
('HEL', 'PAN', 'AMS', 'NYC', 'CAS')
('HEL', 'AMS', 'PAN', 'NYC', 'CAS')
('HEL', 'AMS', 'NYC', 'PAN', 'CAS')
('HEL', 'AMS', 'NYC', 'CAS', 'PAN')
('PAN', 'HEL', 'NYC', 'AMS', 'CAS')
('HEL', 'PAN', 'NYC', 'AMS', 'CAS')
('HEL', 'NYC', 'PAN', 'AMS', 'CAS')
('HEL', 'NYC', 'AMS', 'PAN', 'CAS')
('HEL', 'NYC', 'AMS', 'CAS', 'PAN')
('PAN', 'HEL', 'NYC', 'CAS', 'AMS')
('HEL', 'PAN', 'NYC', 'CAS', 'AMS')
('HEL', 'NYC', 'PAN', 'CAS', 'AMS')
('HEL', 'NYC', 'CAS', 'PAN', 'AMS')
('HEL', 'NYC', 'CAS', 'AMS', 'PAN')
You can user the itertools module for this.您可以为此使用 itertools 模块。
Basically, when doing permutations and combinations, this is a very useful place.基本上,在进行排列组合时,这是一个非常有用的地方。
import itertools
portnames = ["PAN", "AMS", "CAS", "NYC", "HEL"]
x = itertools.permutations(portnames)
y = list(x)
# or this is you want to inspect the loop
# y = []
# for i in x:
# y.append(i)
y
The result is a big list:结果是一个大列表:
[('PAN', 'AMS', 'CAS', 'NYC', 'HEL')
('PAN', 'AMS', 'CAS', 'HEL', 'NYC')
('PAN', 'AMS', 'NYC', 'CAS', 'HEL')
('PAN', 'AMS', 'NYC', 'HEL', 'CAS')
('PAN', 'AMS', 'HEL', 'CAS', 'NYC')
('PAN', 'AMS', 'HEL', 'NYC', 'CAS')
('PAN', 'CAS', 'AMS', 'NYC', 'HEL')
('PAN', 'CAS', 'AMS', 'HEL', 'NYC')
('PAN', 'CAS', 'NYC', 'AMS', 'HEL')
('PAN', 'CAS', 'NYC', 'HEL', 'AMS')
('PAN', 'CAS', 'HEL', 'AMS', 'NYC')
('PAN', 'CAS', 'HEL', 'NYC', 'AMS')
('PAN', 'NYC', 'AMS', 'CAS', 'HEL')
('PAN', 'NYC', 'AMS', 'HEL', 'CAS')
('PAN', 'NYC', 'CAS', 'AMS', 'HEL')
('PAN', 'NYC', 'CAS', 'HEL', 'AMS')
('PAN', 'NYC', 'HEL', 'AMS', 'CAS')
('PAN', 'NYC', 'HEL', 'CAS', 'AMS')
('PAN', 'HEL', 'AMS', 'CAS', 'NYC')
('PAN', 'HEL', 'AMS', 'NYC', 'CAS')
('PAN', 'HEL', 'CAS', 'AMS', 'NYC')
('PAN', 'HEL', 'CAS', 'NYC', 'AMS')
...
..and so on
('HEL', 'NYC', 'PAN', 'CAS', 'AMS'),
('HEL', 'NYC', 'AMS', 'PAN', 'CAS'),
('HEL', 'NYC', 'AMS', 'CAS', 'PAN'),
('HEL', 'NYC', 'CAS', 'PAN', 'AMS'),
('HEL', 'NYC', 'CAS', 'AMS', 'PAN')]
As a side note, whilst your attempt was good, because the output is large and the number of recursions is large, you could get stack overflow.附带说明一下,虽然您的尝试很好,但由于 output 很大并且递归次数很大,您可能会遇到堆栈溢出。
There were two alternative things that you can do:您可以做两件事:
while
or for
loop.while
或for
循环。 However, the itertool.permutations
option is most suitable.但是,
itertool.permutations
选项是最合适的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.