假設有下面一段**:
a =[1
,2,3
,4]b =[5
,6,7
,8,9
]c =[11
,12,13
,14,15
,16,17
,18,19
,20]for item in
(a, b, c)
: item +=[0
]*(10
-len
(item)
)print a
print b
print c
這段**的意思是,有三個列表,需要在長度不為 10 的列表尾部填充 0,讓其長度變為10。輸出如下:
[1,
2,3,
4,0,
0,0,
0,0,
0][5
,6,7
,8,9
,0,0
,0,0
,0][
11,12,
13,14,
15,16,
17,18,
19,20]
這裡沒什麼問題,一切正常。但是,現在變了需求,需要在長度不為 10 的列表的前面填充 0。那麼,我們嘗試做如下的改動:
'''
'''a =[1
,2,3
,4]b =[5
,6,7
,8,9
]c =[11
,12,13
,14,15
,16,17
,18,19
,20]for item in
(a, b, c)
: item =[0
]*(10
-len
(item)
)+ item
print a
print b
print c
直接來看一下輸出:
[1,
2,3,
4][5
,6,7
,8,9
][11,
12,13,
14,15,
16,17,
18,19,
20]
結果卻不是我們想象的那樣。如果你沒有發現問題的所在,就繼續往下看吧。當然,如果你已經看出了其中的端倪,那就不需要在這裡浪費時間了。
按照我們固有的思維,上面的方法是可行,例如下面的例項:
>>
> l =[1
,2,3
,4,5
]>>
> l =[0
]*5+ l
>>
> l[0
,0,0
,0,0
,1,2
,3,4
,5]
這樣的操作讓列表如願以償的得到我們所期望的改變。但是,如果我們在其中多加幾個步驟呢:
'''
'''>>
> l =[1
,2,3
,4,5
]>>
>
id(l)
139935500860952
>>
> l =[0
]*5+ l
>>
> l[0
,0,0
,0,0
,1,2
,3,4
,5]>>
>
id(l)
139935500783272
到此,是不是已經看出問題所在了呢。通過 id() 方法的輸出可以看到,後邊的 「l」 已經不是前邊的 「l」 了。再看看下邊的例子:
>>
> l =[1
,2,3
,4,5
]>>
>
id(l)
139935500861024
>>
> l +=[0
]*5>>
> l[1
,2,3
,4,5
,0,0
,0,0
,0]>>
>
id(l)
139935500861024
>>
> t =(1
,2,3
,4,5
)>>
>
id(t)
139935501840656
>>
> t +=(0
,)*5
>>
> t(1
,2,3
,4,5
,0,0
,0,0
,0)>>
>
id(t)
139935502151336
可以看到,當我們把列表換成元組時,結果又發生了變化。那麼我們對元組使用 + 操作呢:
'''
'''>>
> t =(1
,2,3
,4,5
)>>
>
id(t)
139935501081200
>>
> t =(0
,)*5
+ t>>
> t(0
,0,0
,0,0
,1,2
,3,4
,5)>>
>
id(t)
139935502151336
這與列表結果是一樣的,沒有什麼不同。那麼,再來看看字串呢:
>>
> s =
"hello"
>>
>
id(s)
139935500909712
>>
> s +=
"world"
>>
> s
'helloworld'
>>
>
id(s)
139935500909664
結果如同元組,「s」 在使用 += 拼接乙個字串後,被重新賦了值,已然不是之前的變數。反映在記憶體中就是,「s」 被另外開闢了乙個儲存空間來存放值。
這裡,我們要談的 python 連線符就是 + 與 +=。要注意在 python 中這兩個符號有兩層含義,乙個是運用在數學中的加法運算,乙個是用在序列型別上的拼接功能。不過,作為加法運算子時,也遵循本文討論的使用規則。因為討論這兩個符號,本質上是討論 python 的 immutable 和 mutable,即可變型別與不可變型別。對可變型別來說,我們可以在原地對變數進行修改,也就是說它的儲存空間是可讀可寫的,例如 list;而對於不可變型別來說,它的儲存空間則是唯讀的,無法對其進行修改,如果需要對不可變型別進行某些操作來得到新的結果,則需要重新開闢乙份儲存空間來存放這個新產生的結果。
由以上列舉的例子,我們可以得到如下的結論:
>>
> a =[1
,2,3
,4]>>
> t = a
>>
>
id(a)
139712695835400
>>
>
id(t)
139712695835400
>>
> t +=[0
]*6>>
> t[1
,2,3
,4,0
,0,0
,0,0
,0]>>
>
id(t)
139712695835400
>>
>
id(a)
139712695835400
>>
> a[1
,2,3
,4,0
,0,0
,0,0
,0]>>
>
>>
>
>>
> a =[1
,2,3
,4]>>
> t = a
>>
>
id(a)
139712695835464
>>
>
id(t)
139712695835464
>>
> t =[0
]*6+ t
>>
> t[0
,0,0
,0,0
,0,1
,2,3
,4]>>
> a[1
,2,3
,4]>>
>
id(a)
139712695835464
>>
>
id(t)
139712695835400
這裡, t 是對 a 的乙個引用,就相當於文章開頭例子的 item。用 += 對 t 進行操作實際上是對 a 進行操作,而 += 是原地操作,所以改變 t 時,a 也隨之變化;如果用 + 對 t 進行操作,在將結果賦值給 t,那麼此時的 t 就不再指向 a 了,而是指向[0]*6 + t
,所以 a 沒有被改變。
這裡討論的只是乙個簡單的問題,而我卻用了這麼長的篇幅來談論這個問題,所以我想說的是,對於這些小問題,如果你沒有完全理解,那麼在程式設計過程中可能會給你帶來麻煩。
詳解Python的連線符
目錄 python的連線符主要有 加號 逗號 空格 反斜線 join 的方式 注意,只能連線字串,如果乙個是字串乙個是數字就會報錯 persjfzkpcsrint 這裡是字串 這裡是也是字串 另外,這裡的字串也可以是變數形式 a 這裡是字串 print 這裡是字串 a s 這裡是字串 逗號可以連線字...
bat中的連線符
command1 command2 用來分隔乙個命令列中的多個命令。cmd.exe 執行第乙個命令,然後執行第二個命令。command1 command2 只有在符號 前面的命令成功時,才用於執行該符號後面的命令。cmd.exe 執行第乙個命令,然後只有在第乙個命令執行成功時才執行第二個命令。com...
Python 關於連線符
連線符 連線符 實則是建立了新的物件並占用新的記憶體 dict set不能使用 string 由於python必須為每乙個使用連線符 的字串分配新的記憶體,並產生新的字串。下面兩種方式會更有效 使用格式化操作符 s s hello world hello world 將字串放到列表中,使用join連...