使用多个列表

时间:2016-01-24 00:38:41

标签: python numpy

鉴于

  • m个列表的数量(m可能会有所不同)。
  • 每个列表包含arange()个数字。

需要

  • 找到sum()N的m-tuple(每个列表一个数字)。

我有什么

  • 我可以在静态列表中找到所有组合。

    import numpy as np
    for a in np.arange(0,1,0.01):
        for b in np.arange(0,1,0.01):
            for c in np.arange(0,1,0.01):
                for d in np.arange(0,1,0.01):
                    if (a+b+c+d) == 1.0: 
                        print a,b,c,d
    

我也希望找到一种最佳的计算方法。

3 个答案:

答案 0 :(得分:5)

正如评论中所讨论的那样,范围都是相同的,我们应该使用整数。这是一种非常好的方式。

生成三个数字,而不是生成四个数字并测试它们是否加起来为10,而是将区间[0,10]的分区定义为四个区间。例如,当我们在(3,4,8)处进行切割时,我们添加端点0和10,那么我们就有边界(0,3,4,8,10)。相邻边界之间的差异是(3-0,4-3,8-4,10-8)=(3,1,4,2)。这四个数字加起来为10.这里的代码就是这样做的:

n = 10
import itertools, operator
for cuts in itertools.combinations_with_replacement(range(n+1), 3):
    combi = list(map(operator.sub, cuts + (n,), (0,) + cuts))
    if max(combi) < n:
        print(combi)

打印:

[0, 0, 1, 9]
[0, 0, 2, 8]
[0, 0, 3, 7]
[0, 0, 4, 6]
[0, 0, 5, 5]
[0, 0, 6, 4]
[0, 0, 7, 3]
[0, 0, 8, 2]
[0, 0, 9, 1]
[0, 1, 0, 9]
[0, 1, 1, 8]
[0, 1, 2, 7]
...
...
[7, 2, 0, 1]
[7, 2, 1, 0]
[7, 3, 0, 0]
[8, 0, 0, 2]
[8, 0, 1, 1]
[8, 0, 2, 0]
[8, 1, 0, 1]
[8, 1, 1, 0]
[8, 2, 0, 0]
[9, 0, 0, 1]
[9, 0, 1, 0]
[9, 1, 0, 0]

它非常有效,因为它可以非常直接地生成组合。 if max(combi) < n仅过滤掉[0, 0, 0, 10][0, 0, 10, 0][0, 10, 0, 0][10, 0, 0, 0]

这是你的原版,我的和@ Mijamo之间的速度比较,其中包含100个数字,例如你的例子:

  drum: 21.027 seconds
Stefan:  0.708 seconds
Mijamo: 62.864 seconds

该测试的完整代码:

import itertools, operator
from timeit import timeit

def drum(n):
    out = []
    for a in range(n):
        for b in range(n):
            for c in range(n):
                for d in range(n):
                    if a + b + c + d == n:
                        out.append((a, b, c, d))
    return out

def Stefan(n):
    combinations = (map(operator.sub, cuts + (n,), (0,) + cuts)
                    for cuts in itertools.combinations_with_replacement(range(n+1), 3))
    return [c for c in combinations if max(c) < n]

def Mijamo(n):
    combinations = itertools.product(range(n), repeat=4)
    return [tuple for tuple in combinations if sum(tuple) == n]

for func in drum, Stefan, Mijamo:
    print '%6s: %6.3f seconds' % (func.__name__, timeit(lambda: func(100), number=1))

答案 1 :(得分:2)

可以通过以下方式检索所有组合:

combinations = itertools.product(np.arange(0,1,0.01), repeat = m)

https://docs.python.org/3.5/library/itertools.html#itertools.product

因为它是一个生成器,你可以创建一个新的生成器来返回总和为n的tupples

results = (tuple for tuple in combinations if sum(tuple) == N)

答案 2 :(得分:1)

如何使用&#34;产品&#34;从itertools获得所有可能的m长度元组。然后你只需按元组和== N

的条件进行过滤