Python使用列表推导迭代嵌套列表

时间:2017-01-26 18:35:45

标签: python arrays list-comprehension

我正在研究Euler Project,问题11,其中涉及找到网格中四个相邻数字的所有可能组合的最大乘积。我已将数字拆分为嵌套列表,并使用列表推导来切割相关数字,如下所示:

if x+4 <= len(matrix[x]): #check right
    my_slice = [int(matrix[x][n]) for n in range(y,y+4)]

...等其他基本方向。到现在为止还挺好。但是当我到达对角线时,事情会变得有问题。我尝试使用两个这样的范围:

if x+4 <= len(matrix[x]) and y-4 >=0:# check up, right
    my_slice = [int(matrix[m][n]) for m,n in ((range(x,x+4)),range(y,y+4))]

但这会产生以下错误:

<ipython-input-53-e7c3ebf29401> in <listcomp>(.0)
 48     if x+4 <= len(matrix[x]) and y-4 >=0:# check up, right
---> 49         my_slice = [int(matrix[m][n]) for m,n in ((range(x,x+4)),range(y,y+4))]
ValueError: too many values to unpack (expected 2)

我希望[0,0]的x,y值的索引为['0,0','1,1','2,2','3,3']。使用枚举函数迭代列表似乎没有什么不同,但显然我遗漏了一些东西。

P.S。我为我可怕的变量命名道歉,我正在进行中。

2 个答案:

答案 0 :(得分:0)

您不需要使用两个范围,只需使用一个并应用两次:

my_slice = [int(matrix[m][m-x+y]) for m in range(x,x+4)]

由于n应该附加range(y,y+4),我们知道y-xm之间始终存在差异n range(..)。因此,我们不是使用两个变量,而是可以自己抵消差异。

或者,如果你仍然希望使用两个zip(..)构造,你可以使用my_slice = [int(matrix[m][n]) for m,n in zip(range(x,x+4),range(y,y+4))] 获取生成器列表,同时使用它们并发出元组:

<table class="table table-bordered">
  <thead>
    <tr>
      <th class="text-center">id</th>
      <th class="text-center">Factor A</th>
      <th class="text-center">Factor B</th>
      <th class="text-center">Factor C</th>
    </tr>
  </thead>
  <tbody >
    <tr ng-class="{'info':aggregateData.Mode, 'closed':!aggregateData.Open}">
      <td class="text-center">{{aggregateData.id}}</td>
      <td class="text-center">{{aggregateData.factor_a}}</td>
      <td class="text-center">{{aggregateData.factor_b}}</td>
      <td class="text-center">{{aggregateData.factor_c}}</td>
    </tr>
  </tbody>
</table

但我认为这不会因为元组打包和解包开销而提高性能。

答案 1 :(得分:0)

对于一个对角线,

[int(matrix[x+d][n+d]) for d in range(4)] 另一个[int(matrix[x+d][n-d]) for d in range(4)]

顺便说一句,更好地使用标准矩阵索引名称,即行i和列j。不是xy。这令人困惑。我认为您甚至混淆了自己,例如您的if x+4 <= len(matrix[x])测试x与第二维长度相比,但在第一维中使用它。咦?