Python 如何获得所有可能的排列?
我有一个嵌套列表Python 如何获得所有可能的排列?,python,python-3.x,loops,permutation,combinatorics,Python,Python 3.x,Loops,Permutation,Combinatorics,我有一个嵌套列表 x = [['a', 'b', 'c'], ['d'], ['e', 'f', ['g', ['h', 'i']]]] 我想对子列表中的元素进行所有可能的排列,而不必超出相应的子列表。 预期输出是以下内容的变体: [['c', 'b', 'a'], ['d'], ['f', 'e', ['g', ['i', 'h']]]] [['d'], ['a', 'b', 'c'], ['f', 'e', [['h', 'i'], 'g']]] 每个元素必须保留在它的方括号中 我使用这
x = [['a', 'b', 'c'], ['d'], ['e', 'f', ['g', ['h', 'i']]]]
我想对子列表中的元素进行所有可能的排列,而不必超出相应的子列表。
预期输出是以下内容的变体:
[['c', 'b', 'a'], ['d'], ['f', 'e', ['g', ['i', 'h']]]]
[['d'], ['a', 'b', 'c'], ['f', 'e', [['h', 'i'], 'g']]]
每个元素必须保留在它的方括号中
我使用这台发电机:
def swap(x):
if isinstance(x, list):
res = np.random.choice(x, len(x), replace = False)
return [list(map(ff, res))]
else:
return x
它给出了预期结果的随机变量,但我需要收集它们。我怎么做呢?我应该做:
my_list = []
for i in range(10000): # not necessary 10000, any huge number
my_list.append(ff(yy1))
然后将unique函数应用于我的列表以选择唯一的,或者还有另一个选项?不是特别的pythonic,但我会通过查找索引的排列来实现它,如下图所示:
from itertools import permutations
mylist= [[1], [1,2], [1,2,3]]
combinations = list(permutations([i for i in range(len(mylist))]))
print(combinations)
for item in combinations:
print([mylist[item[i]] for i in range(len(mylist))])
Output:
[(0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0), (2, 0, 1), (2, 1, 0)]
[[1], [1, 2], [1, 2, 3]]
[[1], [1, 2, 3], [1, 2]]
[[1, 2], [1], [1, 2, 3]]
[[1, 2], [1, 2, 3], [1]]
[[1, 2, 3], [1], [1, 2]]
[[1, 2, 3], [1, 2], [1]]
不是特别的pythonic,但我会通过查找索引的排列来处理它,如下图所示:
from itertools import permutations
mylist= [[1], [1,2], [1,2,3]]
combinations = list(permutations([i for i in range(len(mylist))]))
print(combinations)
for item in combinations:
print([mylist[item[i]] for i in range(len(mylist))])
Output:
[(0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0), (2, 0, 1), (2, 1, 0)]
[[1], [1, 2], [1, 2, 3]]
[[1], [1, 2, 3], [1, 2]]
[[1, 2], [1], [1, 2, 3]]
[[1, 2], [1, 2, 3], [1]]
[[1, 2, 3], [1], [1, 2]]
[[1, 2, 3], [1, 2], [1]]
你考虑过使用itertools吗 有明确的组合和排列工具可用 从: itertools.可置换的[,r] 返回连续r长度 iterable中元素的排列 如果未指定r或r为None,则r默认为 生成iterable和所有可能的全长置换 排列按字典排序顺序发出。因此,如果输入 iterable排序后,排列元组将以排序方式生成 秩序 元素被视为唯一的是基于它们的位置,而不是它们的属性 价值因此,如果输入元素是唯一的,则不会重复 每个排列中的值 itertools.combinationsiterable,r 从输入iterable返回元素的r长度子序列 组合按字典排序顺序发出。因此,如果输入 iterable被排序后,组合元组将以排序的方式生成 秩序 元素被视为唯一的是基于它们的位置,而不是它们的属性 价值因此,如果输入元素是唯一的,则不会重复 每个组合中的值
你考虑过使用itertools吗 有明确的组合和排列工具可用 从: itertools.可置换的[,r] 返回连续r长度 iterable中元素的排列 如果未指定r或r为None,则r默认为 生成iterable和所有可能的全长置换 排列按字典排序顺序发出。因此,如果输入 iterable排序后,排列元组将以排序方式生成 秩序 元素被视为唯一的是基于它们的位置,而不是它们的属性 价值因此,如果输入元素是唯一的,则不会重复 每个排列中的值 itertools.combinationsiterable,r 从输入iterable返回元素的r长度子序列 组合按字典排序顺序发出。因此,如果输入 iterable被排序后,组合元组将以排序的方式生成 秩序 元素被视为唯一的是基于它们的位置,而不是它们的属性 价值因此,如果输入元素是唯一的,则不会重复 每个组合中的值 isinstance+itertools.permutations是一个很好的方向,只是您需要它们的一个乘积,以及一些跟踪哪个排列适用于树的哪个部分,我一直在考虑生成树的所有可能遍历:
import itertools
def plan(part,res):
if isinstance(part,list) and len(part)>1:
res.append(itertools.permutations(range(len(part))))
for elem in part:
plan(elem,res)
return res
def remix(part,p):
if isinstance(part,list) and len(part)>1:
coll=[0]*len(part)
for i in range(len(part)-1,-1,-1):
coll[i]=remix(part[i],p)
mix=p.pop()
return [coll[i] for i in mix]
else:
return part
def swap(t):
plans=itertools.product(*plan(t,[]))
for p in plans:
yield remix(t,list(p))
for r in swap([['a', 'b', 'c'], ['d'], ['e', 'f', ['g', ['h', 'i']]]]):
print(r)
plan递归查找包含多个元素的所有实际列表,并为它们创建itertools.permutation
交换调用计划,然后使用itertools.product将置换组合为一个复合巨置换
remix为单个巨置换步骤创建一个实际对象。这有点复杂,因为我不想与跟踪树位置作斗争,相反,remix向后工作,转到最后一个列表,并用当前计划的最后一个组件将其滑动,将其从列表中删除
虽然您的示例有点长,但它似乎是可行的,使用更简单的输入,它有可管理的输出:
24个置换,如预期的那样isinstance+itertools.permutations是一个很好的方向,只需要它们的一个产品,以及一些跟踪哪个置换适用于树的哪个部分,我一直在考虑生成树的所有可能的遍历:
import itertools
def plan(part,res):
if isinstance(part,list) and len(part)>1:
res.append(itertools.permutations(range(len(part))))
for elem in part:
plan(elem,res)
return res
def remix(part,p):
if isinstance(part,list) and len(part)>1:
coll=[0]*len(part)
for i in range(len(part)-1,-1,-1):
coll[i]=remix(part[i],p)
mix=p.pop()
return [coll[i] for i in mix]
else:
return part
def swap(t):
plans=itertools.product(*plan(t,[]))
for p in plans:
yield remix(t,list(p))
for r in swap([['a', 'b', 'c'], ['d'], ['e', 'f', ['g', ['h', 'i']]]]):
print(r)
plan递归查找包含多个元素的所有实际列表,并为它们创建itertools.permutation
交换调用计划,然后使用itertools.product将置换组合为一个复合巨置换
remix为单个巨置换步骤创建一个实际对象。这有点复杂,因为我不想与跟踪树位置作斗争,相反,remix向后工作,转到最后一个列表,并用当前计划的最后一个组件将其滑动,将其从列表中删除
虽然你的例子很好,但它似乎是有效的
有点长,输入简单,输出可控:
24个排列,如预期但子列表中的元素没有排列。例如,还必须有类似于[3,1,2][2,1][1]和[1][2,1,3][1,2]的内容将其定义为函数,然后将其应用于子列表,但子列表中的元素没有排列。例如,还必须有类似于[3,1,2][2,1][1]和[1][2,1,3][1,2]的内容将其定义为一个函数,然后将其应用于子列表,这样您就可以引用文档了。。。但它没有解决这个问题。很高兴你参考了文档。。。但它并没有解决这个问题。