我被要求用一維串列中的元素替換二維串列中的一些元素。規則是將list1的第一行替換為list2。下一行中的元素將被前一行中的每個元素替換 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)。我不確定哪個部分給了我錯誤。
uj5u.com熱心網友回復:
以下是對您的代碼的一些評論以及如何使其執行問題描述的示例:
(1.) 參考與副本: list1 = [[0]*4]*10創建一個 4 元素串列并填充list110 個對它的參考(不是 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)]為每個索引提供一個不同的串列(總共 10 個)list1:
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。
這是一種執行您所要求的操作的簡便方法,它將用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))]
uj5u.com熱心網友回復:
發生的原因是您正在處理 list1 的 0 個元素的副本,因此無論何時您進一步修改所有內容都將被新值替換,它不是參考中相同物件的副本。
for i in range(9):
tmp = []
for j in range(4):
tmp.append(list2[j]*(3**i))
list1[i] = tmp
這就是你所需要的
uj5u.com熱心網友回復:
您可以使用 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]
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/461258.html
上一篇:如何從for回圈轉換為“過濾器”
下一篇:我的二維陣列被分配了錯誤的值
