我来自C ++作为我的第一个编程语言,我刚刚进入python并且我正在寻找一种从列表中切换数字的方法,在C ++中这将通过使用指针移动它们来完成循环,但是这次我需要生成列表A的所有排列到Python中的列表B
列表A(起始者列表)和列表B(结果列表)
A= 1234
B= 4231
程序必须按顺序显示所有可能的组合,同时只移动2个数字,直到A列表成为B列表(以下示例简化为4个数字,可能不会显示所有组合)< / p>
[1,2,3,4]
[1,2,4,3]
[1,4,2,3]
[4,1,2,3]
[4,2,1,3]
[4,2,3,1]
为了完成这个,我找到了itertools模块,它包含很多函数,但到目前为止还没有能够实现到很多函数,下面的代码实现了它需要的东西,不过它不会成对或按顺序移动数字
import itertools
from itertools import product, permutations
A = ([1,2,3,4])
B = ([4,2,3,1])
print "\n"
print (list(permutations(sorted(B),4)))
我正在考虑添加一段时间(A!= B)然后停止排列,我已经尝试了这个但我不熟悉pythons语法,任何有关如何实现这一点的帮助将不胜感激
答案 0 :(得分:2)
我假设并不真正需要对输入列表进行排序,
from itertools import permutations
A = ([4, 3, 2, 1])
B = ([1,2,4, 3])
def print_combinations(start, target):
# use list(permutations(sorted(start), len(start))) if sorting of start is really required
all_perms = list(permutations(start, len(start)))
if tuple(target) not in all_perms:
# return empty list if target is not found in all permutations
return []
# return all combinations till target(inclusive)
# using list slicing
temp = all_perms[: all_perms.index(tuple(target)) + 1]
return temp
print print_combinations(A, B)
答案 1 :(得分:1)
你所要求的并不完全清楚。我想你要求一种pythonic方式来交换列表中的两个元素。在Python中,通常将数据结构分为不可变和可变。在这种情况下,您可能会谈论元组或列表。
假设您要交换元素i
和j
,j
更大。
对于不可变元组,pythonic方法将通过切片生成一个新元组:
next = (current[:i] + current[j:j+1] + current[i+1:j]
+ current[i:i+1] + current[j+1:])
对于可变列表,与C ++相同的是pythonic,尽管它在Python中更漂亮:
list[i],list[j] = list[j],list[i]
或者你可能会询问如何解决你的排列问题,在这种情况下,答案是itertools并没有提供太多帮助。我会建议深度优先搜索。
答案 2 :(得分:1)
假设您正在询问解决此排列问题的最佳方法 - 这是一个不同的答案:
将所有排列视为一组。 itertools.permutations
按某种顺序生成所有这些排列。如果你想找到所有或部分排列,那就是你想要的。但那并不是你想要的。您正试图通过这些排列找到路径。 itertools.permutations
以 顺序生成所有排列,但不一定是您想要的顺序。当然不是所有订单:它只生成一次。
因此,您可以生成所有排列并将其视为网络的节点。然后,只要通过单个交换连接节点,就可以链接节点,以获得图形。这被称为permutohedron。然后,您可以在该图表上进行搜索,以找到您感兴趣的从a
到b
的所有无循环路径。这当然是可能的,但它并不是最佳的。提前构建整个图表是一个不必要的步骤,因为它可以很容易地按需生成。
以下是一些Python代码:它通过在需要时为节点生成邻居来生成对permutohedron的深度优先搜索。但它并没有使用itertools
。
a = (1,2,3,4)
b = (4,2,3,1)
def children(current):
for i in range(len(a)-1):
yield (current[:i] + (current[i+1],current[i]) +
current[i+2:])
def dfs(current,path,path_as_set):
path.append(current)
path_as_set.add(current)
if current == b:
yield path
else:
for next_perm in children(current):
if next_perm in path_as_set:
continue
for path in dfs(next_perm,path,path_as_set):
yield path
path.pop()
path_as_set.remove(current)
for path in dfs(a,[],set()):
print(path)
如果您真的对使用itertools.permutations
感兴趣,那么您要学习的对象实际上是:
itertools.permutations(itertools.permutations(a))
这将通过一组排列生成所有可能的路径。您可以通过拒绝任何不在a
开始且包含非单一交换步骤的拒绝。但这是一个非常糟糕的方法:这个列表很长。