如何创建满足特定条件的所有可能列表的列表?

时间:2017-04-29 03:41:02

标签: python list list-comprehension

我目前正在尝试使用'强力'方法来检查所有可能的路径,进行项目Euler问题18(https://projecteuler.net/problem=18)。到目前为止,我一直在尝试较小的“模型”三角形。 我正在使用列表推导来创建列表列表,其中内部列表将包含该行的索引,例如:

lst = [[a,b,c,d] for a in [0] for b in [0,1] for c in [0,1,2] for d in 
[0,1,2,3] if b == a or b == a + 1 if c == b or c == b + 1 if d == c or d == 
c + 1]

这给了我想要的列表清单,即:

[[0,0,0,0],[0,0,0,1],[0,0,1,1],[0,0,1,2],[0,1,1,1],[0,1,1,2],[0,1,2,2],
[0,1,2,3]]

注意:if条件确保它只移动到三角形的下一行中的相邻数字,以便

lst[i][j] = lst[i][j-1] or lst[i][j] = lst[i][j]-1

在我达到这一点之后,我打算对每个内部列表,我将采用与这些索引相关的数字(所以[0,0,0,0]将是3,7,2,8)并总结他们,这种方式得到所有可能的总和,然后取最大值。

问题在于,如果我将它扩展到大三角形,那么我将有15个'和'如果在我的列表理解中。似乎必须有一个更简单的方法!我对Python很陌生,所以希望我能用到的一些显而易见的功能到目前为止我已经错过了!

1 个答案:

答案 0 :(得分:0)

多么有趣的问题!这是一个简单的蛮力方法,请注意使用itertools生成所有组合,然后排除连续行索引相差多个的所有情况。

import itertools
import numpy as np

# Here is the input triangle
tri = np.array([[3],[7,4],[2,4,6],[8,5,9,3]])
indices = np.array([range(len(i)) for i in tri])

# Generate all the possible combinations
indexCombs = list(itertools.product(*indices))

# Generate the difference between indices in successive rows for each combination
diffCombs = [np.array(i[1:]) - np.array(i[:-1]) for i in indexCombs]

# The only combinations that are valid are when successive row indices differ by 1 or 0
validCombs = [indexCombs[i] for i in range(len(indexCombs)) if np.all(diffCombs[i]**2<=1)]

# Now get the actual values from the triangle for each row combination
valueCombs = [[tri[i][j[i]] for i in range(len(tri))] for j in validCombs]

# Find the sum for each combination
sums = np.sum(valueCombs, axis=1)

# Print the information pertaining to the largest sum
print 'Highest sum: {0}'.format(sums.max())
print 'Combination: {0}'.format(valueCombs[sums.argmax()])
print 'Row indices: {0}'.format(indexCombs[sums.argmax()])

输出结果为:

  

最高金额:23

     

组合:[3,7,4,9]

     

行索引:(0,0,1,0)

不幸的是,这在计算上是非常密集的,所以它不会使用大三角形 - 但是肯定有一些概念和工具可以扩展以尝试让它工作!