目前我正在尝试从两个嵌套循环中对数字求和。我非常接近,但出于某种原因,数字没有正确添加。
def addTables(table1,table2):
counter = 0
index = 0
table3 = [[None] * len(table1[0])] * len(table1)
print(table3)
for row in table1:
for i in table1[0]:
table3[counter][index] = table1[counter][index] + table2[counter][index]
index = index +1
index = 0
counter = counter + 1
print (table3)
我的值为table1 = [[1,2,3],[4,5,6]]
和table2 = [[1,2,3],[4,5,6]]
。
由于某种原因,它正在打印
[[None, None, None], [None, None, None]]
[[2, 4, 6], [2, 4, 6]]
[[8, 10, 12], [8, 10, 12]]
但我希望它打印
[[None, None, None], [None, None, None]]
[[2, 4, 6], [None, None, None]]
[[2, 4, 6], [8, 10, 12]]
我认为这一行是错误的,但我不知道如何修复它。
table3[counter][index] = table1[counter][index] + table2[counter]
答案 0 :(得分:3)
问题在于
table3 = [[None] * len(table1[0])] * len(table1)
乘以列表实际上会复制对其项目的引用;它不会复制列表中的项目。要查看会发生什么,请查看以下代码:
subtable = [None] * len(table1[0])]
# subtable = [None, None, None]
table3 = [subtable] * len(table1)
# table3 = [subtable, subtable]
因此,table3[0]
和table3[1]
实际上是相同的列表。因此,当您设置table3[0][0]
时,您实际上正在修改subtable
,table3[0]
和table3[1]
!
您可以自己看到这种效果:
>>> table3 = [[None] * 3] * 2
>>> table3
[[None, None, None], [None, None, None]]
>>> table3[0][1] = 5
>>> table3
[[None, 5, None], [None, 5, None]]
您可以使用list comprehensions构建table3
:
>>> table3 = [[None for x in table1[0]] for y in table1]
>>> table3
[[None, None, None], [None, None, None]]
>>> table3[0][1] = 5
>>> table3
[[None, 5, None], [None, None, None]]
或者,对内部列表使用列表乘法很好。 (这是因为None
的引用被替换,而子列表的引用被修改了:
>>> table3 = [[None] * len(table1[0]) for y in table1]
>>> table3
[[None, None, None], [None, None, None]]
>>> table3[0][1] = 5
>>> table3
[[None, 5, None], [None, None, None]]
但这种微妙之处可能令人困惑。使用嵌套列表理解更加明确。
但就个人而言,我不会提前建立这样的名单。相反,我建议从一个空列表开始,然后在你去的时候附加
table3 = []
for row in table1:
sumrow = []
index = 0
for i in table1[0]:
sumrow.append(table1[counter][index] + table2[counter][index])
index += 1
table3.append(sumrow)
counter += 1
并且,在此基础上,直接迭代列表通常更清晰,而不是迭代它们的索引。您可以使用zip
迭代两个大小相同的列表,如下所示:
for row1, row2 in zip(table1, table2):
sumrow = []
for item1, item2 in zip(row1, row2):
sumrow.append(item1 + item2)
table3.append(sumrow)
一旦我们在那里,我们可以将sumrow
表达为列表理解:
for row1, row2 in zip(table1, table2):
table3.append([item1 + item2 for item1, item2 in zip(row1, row2)])
请注意,通过使用sum
将map
应用于每对,也可以实现列表推导中的这种成对添加:
for row1, row2 in zip(table1, table2):
table3.append(list(map(sum, zip(row1, row2))))
然后我们也可以通过列表理解来替换外部for循环。
table3 = [list(map(sum, zip(row1, row2))) for row1, row2 in zip(table1, table2)]
通过对行使用列表解包可以略微改进:
table3 = [list(map(sum, zip(*rows))) for rows in zip(table1, table2)]
如果这实际上是最好/最易读的方法,我有点矛盾,所以也许我应该在几个版本之前停止过。但是,嘿,我们在这里;)