首頁  >  問答  >  主體

請問python中為什麼我用for迴圈對巢狀列表進行賦值時,都是以i的最終值來計算的?

有兩個例子,第一個如下,

a=[0]*5
for i in range(5):
    a[0]=i+3

此時,a=[3,4,5,6,7]
第二個如下:

a=[[0,0]]*5
for i in range(5):
    a[0]=i+3

這時候,a=[[7, 0], [7, 0], [7, 0], [7, 0], [7, 0]]

為什麼會出現這種情況呢,我的第二種寫法有什麼不對嗎?
新手求大神指教!

扔个三星炸死你扔个三星炸死你2686 天前930

全部回覆(3)我來回復

  • 大家讲道理

    大家讲道理2017-06-12 09:27:09

    你這裡犯了2個問題:
    第一個, 也就是樓上說得, 你一直是修改a[0]的值, 你並沒有將變化的i放入列表去處理, 或者說,你漏了把i寫進題目中的程式碼:
    正確方法:

    a = [0] * 5
    for i in range(5):
        a[i] = i + 3
    print a

    第二個問題, 也就是你上面問得, 為什麼a=[[0,0]]*5這種定義方法, 結果出來發現全部都是a=[[7, 0], [7 , 0], [7, 0], [7, 0], [7, 0]]
    這個問題和第一個問題有個相同之處, 就是你應該是忘了寫a[i][ 0] = i + 3,
    其次就是: 如果用[[0, 0]] * 5這樣的方式產生的列表, 裡面的全部都這是引用, 都是同一個物件, 並不是5個物件! 看例子:

    a = [[0, 0]] * 5
    print a
    print id(a[0])
    print id(a[1])
    print id(a[2])
    
    # 输出
    [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]
    42455688
    42455688
    42455688

    可以透過id值看到, 他們都是一樣的地址, 所以列表中的5個物件, 全是同一個, 所以當你執行a[i][0]= i+3時, 不管你修改第幾個元素, 最終都只是修改同一個列表而已!
    所以如果想試下你想要的效果, 你就不能用那種方式快速生成列表,只能用下面的方法:

    a = [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], ]
    for i in range(5):
        a[i][0] = i + 3
    print a
    
    # 输出
    [[3, 0], [4, 0], [5, 0], [6, 0], [7, 0]]
    

    回覆
    0
  • 漂亮男人

    漂亮男人2017-06-12 09:27:09

    因為你要用i 變數進行迭代,你總是改變0的話,a[0] 當然被覆蓋了,為最後一次的值
    第一次程式碼,也得不出a=[3,4,5, 6,7],你得用i變數

    In [156]: a=[0]*5 
     ...: for i in range(5):
     ...:     a[0]=i+3
     ...:
    
    In [157]: a
    Out[157]: [7, 0, 0, 0, 0]
    
    In [159]: a=[0]*5
         ...: for i in range(5):
         ...:     a[i]=i+3
         ...:
         ...:
    
    In [160]:
    
    In [160]: a
    Out[160]: [3, 4, 5, 6, 7]

    第二次代碼:

    In [163]: a=[[0,0]]*5
         ...: for i in range(5):
         ...:     a[0]=i+3
         ...:
    
    In [164]: a
    Out[164]: [7, [0, 0], [0, 0], [0, 0], [0, 0]]
    
    In [165]: a=[[0,0]]*5
         ...: for i in range(5):
         ...:     a[i]=i+3
         ...:
         ...:
    
    In [166]: a
    Out[166]: [3, 4, 5, 6, 7]

    好像是你程式碼寫錯了,我猜你想問這個問題

    In [168]: a=[[0,0]]*5
     ...: for i in range(5):
     ...:     a[i][0]=i+3
     ...:
     ...:
     ...:
    
    In [169]: a
    Out[169]: [[7, 0], [7, 0], [7, 0], [7, 0], [7, 0]]

    你可以把a印出來

    In [175]: a=[[0,0]]*5
     ...: for i in range(5):
     ...:     a[i][0]=i+3
     ...:     print(a,id(a[i]))
     ...:
    [[3, 0], [3, 0], [3, 0], [3, 0], [3, 0]] 93411808
    [[4, 0], [4, 0], [4, 0], [4, 0], [4, 0]] 93411808
    [[5, 0], [5, 0], [5, 0], [5, 0], [5, 0]] 93411808
    [[6, 0], [6, 0], [6, 0], [6, 0], [6, 0]] 93411808
    [[7, 0], [7, 0], [7, 0], [7, 0], [7, 0]] 93411808

    @Lin_R 說的是正確的

    回覆
    0
  • phpcn_u1582

    phpcn_u15822017-06-12 09:27:09

    其實就是第2種方式是共享的,而不是單獨形式了。因為此時是列表,是可變的,而第1種方式是數字,是不可變的。

    回覆
    0
  • 取消回覆