Python3 - 3个变量= x的所有可能组合

sb2*_*894 1 python python-itertools python-3.x

我试图找到所有可能的组合,其中3个变量可以=某个数字.

x = (10,11,12,13,14,15)
y = (10,11,12,13,14,15)
z = (10,11,12,13,14,15)
answer = 45
Run Code Online (Sandbox Code Playgroud)

我将如何使用itertools找到每个组合

x + y + z = 45
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我希望python打印(15,15,15)但是,如果答案是=不同的数字,如30,它将打印x,y,z的每个组合,当添加时将= 45.

Aja*_*234 6

你可以使用itertools.product:

import itertools
x = (10,11,12,13,14,15)
y = (10,11,12,13,14,15)
z = (10,11,12,13,14,15)
answer = 45
final_results = [i for i in itertools.product(x, y, z) if sum(i) == answer]
Run Code Online (Sandbox Code Playgroud)

输出:

[(15, 15, 15)]
Run Code Online (Sandbox Code Playgroud)


Mr.*_*. T 6

您可以使用列表推导而不是 itertools

x = (10,11,12,13,14,15)
y = (10,11,12,13,14,15)
z = (10,11,12,13,14,15)
answer = 35

res = [(i, j, answer - i - j) for i in x for j in y if (answer - i - j) in set(z)]

print(res)
Run Code Online (Sandbox Code Playgroud)

正如@RoryDaulton在评论中所指出的,这种方法的优点在于它是一种O(n ^ 2)方法,结合O(1)查询时间进行测试,如果answer-x-y是的话z.对三个列表进行预分类,这z是最长的列表,应该减少此操作所需的时间.

我也测量了执行时间.测试清楚地表明保罗的代码是最快的:

n = 100
x, y, z = map(list, map(range, 3*(2 * n,)))
any(map(random.shuffle, (x, y, z)))
x, y, z = x[:n], y[:n], z[:n]
answer = 4 * n

def f1(): #team Ajax
    final_results = [i for i in itertools.product(x, y, z) if sum(i) == answer]
    return final_results

def f2(): #team Pie
    res = [(i, j, answer - i - j) for i in x for j in y if (answer - i - j) in set(z)]
    return res

def f3(): #team Paul
    xy = sorted(itertools.product(x, y), key=sum)
    xy = {k: list(v) for k, v in itertools.groupby(xy, sum)}
    xyz = [(a, b, c) for c in z for a, b in xy.get(answer-c, ())]
    return xyz

repeats = 10
print("f1", timeit.repeat("f1()", "from __main__ import f1", number = repeats))
>>>f1 [1.741] #team Ajax
print("f2", timeit.repeat("f2()", "from __main__ import f2", number = repeats))
>>>f2 [0.221] #team Pie
print("f3", timeit.repeat("f3()", "from __main__ import f3", number = repeats))
>>>f3 [0.051] #team Paul
Run Code Online (Sandbox Code Playgroud)

(它只显示每个程序的最快值)