无法使用 for 循环将二维列表中的元素替换为一维列表
Having trouble replacing elements in a 2d list with a 1d list using for-loops
我被要求用一维列表中的元素替换二维列表中的一些元素。规则是用 list2 替换 list1 的第一行。下一行中的元素将被前一行中的每个元素替换 3 次。因此第二行将包含 33、39、45 和 51,第三行将包含 99、117、135 和 153 ...一直到第 10 行。
这是我的代码:
list1 = [[0]*4]*10
list2 = [11,13,15,17]
list1[0] = list2
i = 1
for i in range(9):
j = 0
for j in range(4):
list1[i][j] = list2[j]*(3**i)
j+=1
i+=1
这段代码我得到的结果基本上只有第一行是正确的,但之后的其余行都是72171、85293、98415和111537(即3到8)。我不确定是哪个部分给我的错误。
以下是对您的代码的一些评论,以及如何使其按照问题所述执行操作的示例:
(1.) 引用与副本: list1 = [[0]*4]*10
创建一个 4 元素列表并用 10 个引用填充 list1
(不是 10它的副本)。
有关这意味着什么的示例,请观看:
list1 = [[0]*4]*10
list1[1][0] = 33
list1[1][1] = 39
list1[1][2] = 45
list1[1][3] = 51
print(list1)
...给出这个:
[[33, 39, 45, 51], [33, 39, 45, 51], [33, 39, 45, 51], [33, 39, 45, 51], [33, 39, 45, 51], [33, 39, 45, 51], [33, 39, 45, 51], [33, 39, 45, 51], [33, 39, 45, 51], [33, 39, 45, 51]]
换句话说,更新 list1
中的一个列表元素会更新所有元素,因为 list1
的每个元素都只是对同一列表的引用。
如果这不是您想要的,您可以使用 list1 = [[0]*4 for _ in range(10)]
来为 list1
中的每个索引提供一个不同的列表(总共 10 个):
list1 = [[0]*4 for _ in range(10)]
list1[1][0] = 33
list1[1][1] = 39
list1[1][2] = 45
list1[1][3] = 51
print(list1)
... 给出:
[[0, 0, 0, 0], [33, 39, 45, 51], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
您编写的代码往往暗示需要采用上述第二种方法。
(2.) 假设嵌套列表无法替换的代码修复: 从问题中不清楚是否允许替换 list1
中的每个列表以获得所需的值,或者如果您希望保留嵌套列表并简单地修改它们的数字内容。
如果不允许列表替换,那么你的代码可以这样重写:
list1 = [[0]*4 for _ in range(10)]
list2 = [11,13,15,17]
list1[0][:] = list2
for i in range(9):
for j in range(4):
list1[i + 1][j] = list2[j]*(3**(i + 1))
print(list1)
...给予:
[[11, 13, 15, 17], [33, 39, 45, 51], [99, 117, 135, 153], [297, 351, 405, 459], [891, 1053, 1215, 1377], [2673, 3159, 3645, 4131], [8019, 9477, 10935, 12393], [24057, 28431, 32805, 37179], [72171, 85293, 98415, 111537], [216513, 255879, 295245, 334611]]
请注意,对您的代码进行了这些更改:
- 更改了
list1
的初始化以分配 10 个不同的嵌套列表。
- 消除了
i = 1
(不需要因为for
循环负责初始化i
),j = 0
(类似原因),j+=1
(不是需要因为 for
循环负责更新 j
) 和 i+=1
(类似的原因)。
- 已将
list1[i][j]
更改为 list1[i + 1][j]
以修复索引。
- 已将
3**i
更改为 3**(i + 1)
以计算正确的乘数。
(3.)假设嵌套列表可以被替换的代码修复:在这种情况下,你的循环逻辑可以被简化并且你不需要在初始化时使用嵌套列表list1
.
这是一个 long-hand 方法来完成您的要求,它将用具有所需值的新嵌套列表覆盖 list1
的内容:
list1 = [None] * 10
list2 = [11,13,15,17]
list1[0] = list2
mul = 3
for i in range(1, len(list1)):
temp = [0] * len(list2)
for j in range(len(list2)):
temp[j] = mul * list2[j]
list1[i] = temp
mul *= 3
print(list1)
这是一种在循环中使用列表理解的方法:
list1 = [None] * 10
list2 = [11,13,15,17]
list1[0] = list2
mul = 3
for i in range(1, len(list1)):
list1[i] = [mul * v for v in list2]
mul *= 3
print(list1)
最后,这是一个非常紧凑的嵌套列表理解方法:
list1 = [None] * 10
list2 = [11,13,15,17]
list1 = [[(3 ** i) * v for v in list2] for i in range(len(list1))]
发生这种情况的原因是您正在处理 list1 的 0 个元素的副本,因此每当您进一步修改时,所有内容都将替换为新值,它不是引用中相同对象的副本。
for i in range(9):
tmp = []
for j in range(4):
tmp.append(list2[j]*(3**i))
list1[i] = tmp
这就是您所需要的
您可以使用 numpy 数组使这更容易:
import numpy as np
list1 = np.zeros((10,4), dtype=int)
list1[0] = [11,13,15,17]
for i in range(1,10):
list1[i] = 3*list1[i-1]
我被要求用一维列表中的元素替换二维列表中的一些元素。规则是用 list2 替换 list1 的第一行。下一行中的元素将被前一行中的每个元素替换 3 次。因此第二行将包含 33、39、45 和 51,第三行将包含 99、117、135 和 153 ...一直到第 10 行。
这是我的代码:
list1 = [[0]*4]*10
list2 = [11,13,15,17]
list1[0] = list2
i = 1
for i in range(9):
j = 0
for j in range(4):
list1[i][j] = list2[j]*(3**i)
j+=1
i+=1
这段代码我得到的结果基本上只有第一行是正确的,但之后的其余行都是72171、85293、98415和111537(即3到8)。我不确定是哪个部分给我的错误。
以下是对您的代码的一些评论,以及如何使其按照问题所述执行操作的示例:
(1.) 引用与副本: list1 = [[0]*4]*10
创建一个 4 元素列表并用 10 个引用填充 list1
(不是 10它的副本)。
有关这意味着什么的示例,请观看:
list1 = [[0]*4]*10
list1[1][0] = 33
list1[1][1] = 39
list1[1][2] = 45
list1[1][3] = 51
print(list1)
...给出这个:
[[33, 39, 45, 51], [33, 39, 45, 51], [33, 39, 45, 51], [33, 39, 45, 51], [33, 39, 45, 51], [33, 39, 45, 51], [33, 39, 45, 51], [33, 39, 45, 51], [33, 39, 45, 51], [33, 39, 45, 51]]
换句话说,更新 list1
中的一个列表元素会更新所有元素,因为 list1
的每个元素都只是对同一列表的引用。
如果这不是您想要的,您可以使用 list1 = [[0]*4 for _ in range(10)]
来为 list1
中的每个索引提供一个不同的列表(总共 10 个):
list1 = [[0]*4 for _ in range(10)]
list1[1][0] = 33
list1[1][1] = 39
list1[1][2] = 45
list1[1][3] = 51
print(list1)
... 给出:
[[0, 0, 0, 0], [33, 39, 45, 51], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
您编写的代码往往暗示需要采用上述第二种方法。
(2.) 假设嵌套列表无法替换的代码修复: 从问题中不清楚是否允许替换 list1
中的每个列表以获得所需的值,或者如果您希望保留嵌套列表并简单地修改它们的数字内容。
如果不允许列表替换,那么你的代码可以这样重写:
list1 = [[0]*4 for _ in range(10)]
list2 = [11,13,15,17]
list1[0][:] = list2
for i in range(9):
for j in range(4):
list1[i + 1][j] = list2[j]*(3**(i + 1))
print(list1)
...给予:
[[11, 13, 15, 17], [33, 39, 45, 51], [99, 117, 135, 153], [297, 351, 405, 459], [891, 1053, 1215, 1377], [2673, 3159, 3645, 4131], [8019, 9477, 10935, 12393], [24057, 28431, 32805, 37179], [72171, 85293, 98415, 111537], [216513, 255879, 295245, 334611]]
请注意,对您的代码进行了这些更改:
- 更改了
list1
的初始化以分配 10 个不同的嵌套列表。 - 消除了
i = 1
(不需要因为for
循环负责初始化i
),j = 0
(类似原因),j+=1
(不是需要因为for
循环负责更新j
) 和i+=1
(类似的原因)。 - 已将
list1[i][j]
更改为list1[i + 1][j]
以修复索引。 - 已将
3**i
更改为3**(i + 1)
以计算正确的乘数。
(3.)假设嵌套列表可以被替换的代码修复:在这种情况下,你的循环逻辑可以被简化并且你不需要在初始化时使用嵌套列表list1
.
这是一个 long-hand 方法来完成您的要求,它将用具有所需值的新嵌套列表覆盖 list1
的内容:
list1 = [None] * 10
list2 = [11,13,15,17]
list1[0] = list2
mul = 3
for i in range(1, len(list1)):
temp = [0] * len(list2)
for j in range(len(list2)):
temp[j] = mul * list2[j]
list1[i] = temp
mul *= 3
print(list1)
这是一种在循环中使用列表理解的方法:
list1 = [None] * 10
list2 = [11,13,15,17]
list1[0] = list2
mul = 3
for i in range(1, len(list1)):
list1[i] = [mul * v for v in list2]
mul *= 3
print(list1)
最后,这是一个非常紧凑的嵌套列表理解方法:
list1 = [None] * 10
list2 = [11,13,15,17]
list1 = [[(3 ** i) * v for v in list2] for i in range(len(list1))]
发生这种情况的原因是您正在处理 list1 的 0 个元素的副本,因此每当您进一步修改时,所有内容都将替换为新值,它不是引用中相同对象的副本。
for i in range(9):
tmp = []
for j in range(4):
tmp.append(list2[j]*(3**i))
list1[i] = tmp
这就是您所需要的
您可以使用 numpy 数组使这更容易:
import numpy as np
list1 = np.zeros((10,4), dtype=int)
list1[0] = [11,13,15,17]
for i in range(1,10):
list1[i] = 3*list1[i-1]