给定两个数字r
和s
,我想得到n
+-r
和{+-s
的所有排列的列表。例如(使用r=3.14
和s=2.71
)
n = 1
m = 1
out = [
(+r, +s), (+r, -s), (-r, +s), (-r, -s),
(+s, +r), (+s, -r), (-s, +r), (-s, -r)
]
^{pr2}$
使用itertools.product([+r, -r], repeat=n)
我可以分别得到r
和{
效率并不过分重要,所以我不介意有一个解决方案,它会产生许多重复的结果,但后来却使它们独一无二。在
您还可以将}的{}与{}和{}的{}结合起来。这样,整个结构的可读性就更好了
r
和{更新:添加了通用解决方案。在
下面的解决方案在代码中稍微复杂一些,但不会产生重复的元素,并且可以延迟计算:
输出:
^{pr2}$说明
我们可以将输出看作是包含
n
+/-r
元素和m
+/-s
元素的置换,或者换句话说,n
+m
元素的元组,其中n
是+/-r
,其余的是+/-s
。idx
包含元组,其中包含+/-r
元素的所有可能位置;例如,对于第一个结果,它是(0,)
。在然后,对于这些元组中的每一个}中的索引是}。因此,对于
i
我们在vs
中创建“template”元组,它们只是大小为n
+m
,其中{r
,其余的是{idx
中的元组(0,)
,您将得到(r, s, s)
。如果n
+m
很大,您可以考虑上一步idx = map(set, idx)
,以获得更快的in
操作,但我不确定在哪一步值得这样做。在最后,对于
v
中的每个模板vi
,我需要考虑对每个元素使用正值和负值的所有可能性。所以它是(+vi[0], -vi[0]), (+vi[1], -vi[1]), ...
的笛卡尔积。最后,你只需要把这些产品的每一个发生器连接起来就可以得到最终的结果。在通解
要为任意数量的不同元素构建问题的通用解决方案,需要考虑索引集的分区。例如,对于
n = 3
和m = 5
,所有可能的方法都可以将{0, 1, 2, 3, 4, 5, 6, 7}
分成大小为3和5的两部分。下面是一个实现方法:想法是一样的,您构建“模板”(这次它们包含值的索引,而不是值本身),然后从中生成笛卡尔积。在
首先使用
product
,然后在每个元素上使用permutations
。{cd3>删除所有重复结果并传递:相关问题 更多 >
编程相关推荐