python - itertools.permutations 是否有模式
问题描述
当我迭代 itertools.permutations 时,我想知道特定数字组合会出现在哪些索引处,而不是慢慢地迭代整个事物。
例如:
当我有一个等于 foo 的列表时list(itertools.permutations(range(10)))
,我想知道在哪些索引处第一个字符将是零,而第十七个字符将是三。一个简单的方法是检查每个组合,看看它是否符合我的要求。
n = 10
foo = list(itertools.permutations(range(n)))
solutions = []
for i, permutation in foo:
if permutation[0] == 0 and permutation[16] == 3:
solutions.append(i)
但是,随着 n 变大,这会变得非常慢,并且内存效率非常低。
有没有我可以使用的模式,而不是创建一个长列表,我可以简单地说,如果(a*i+b)%c == 0
那时我知道它会适合我的模式。
编辑:实际上我将有许多条件,其中一些还涉及两个以上的职位,因此我希望通过结合这些条件,我可以将可能性的数量限制在可行的程度。此外,100 可能有点大,我预计 n 不会大于 20。
解决方案
您需要在非固定元素的排列与注册了固定单元格的相应排列之间进行映射。例如,如果您计算 list 上[0, 1, 2, 3, 4]
的排列并要求值 1 表示零单元格,值 2 表示第三个单元格,则排列(0, 4, 3)
将映射到(1, 0, 4, 2, 3)
. 我知道,元组对这种情况并不友好,因为它们是不可变的,但列表的insert
方法在这里非常有用。这就是为什么我将它们转换为列表,然后再转换回元组。
import itertools
def item_padding(item, cells):
#returns padding of item, e.g. (0, 4, 3) -> (1, 0, 4, 2, 3)
listed_item = list(item)
for idx in sorted(cells):
listed_item.insert(idx, cells[idx])
return tuple(listed_item)
array = range(5)
cells = {0:1, 3:2} #indexes and their fixed values
remaining_items = set(list(array)) - set(list(cells.values()))
print(list(map(lambda x: item_padding(x, cells), itertools.permutations(remaining_items))))
输出:
[(1, 0, 3, 2, 4), (1, 0, 4, 2, 3), (1, 3, 0, 2, 4), (1, 3, 4, 2, 0), (1, 4, 0, 2, 3), (1, 4, 3, 2, 0)]
总而言之,列表转换和迭代一样慢。尽管如此,我认为这个算法在概念上是一个很好的例子,它揭示了这里可以做什么。numpy
如果您确实需要优化它,请改用它。
更新:
如果array
是range(12)
(使用 3628800 排列),它在我的笔记本电脑上工作 6 秒。它是返回未填充元组的三倍。
推荐阅读
- kubernetes - GKE - 集群创建完成后升级集群主服务器
- javascript - 带有阴影根的元素会破坏文本选择
- javascript - 将数据传递给模态:Property/method props undefined & TypeError: Cannot read property product of undefined
- mysql - 将N个数组合并为一个?
- c# - 在表上引入 FOREIGN KEY 约束可能会导致引用自身的类的循环或多个级联路径
- php - 我正在努力获取 api 任何功能
- r - Error_bar 和练习
- algorithm - 允许图的并发游走的算法
- c# - 如何在没有管理员访问权限的情况下以编程方式卸载 UWP 应用程序 c#
- c# - 如何将 C# 类映射到角度对象