Python中可變序列的一些坑

2021-09-29 18:16:01 字數 3308 閱讀 3773

聽說面試官比較喜歡這些坑。

預設引數有個最大的坑,演示如下:

先定義乙個函式,傳入乙個 list,新增乙個end再返回:

def

add_end

(l=)

:'end'

)return l

當你正常呼叫時,結果似乎不錯:

>>

> add_end([1

,2,3

])[1

,2,3

,'end'

]>>

> add_end(

['x'

,'y'

,'z'])

['x'

,'y'

,'z'

,'end'

]

當你使用預設引數呼叫時,一開始結果也是對的:

>>

> add_end()[

'end'

]

但是,再次呼叫add_end()時,結果就不對了:

>>

> add_end()[

'end'

,'end'

]>>

> add_end()[

'end'

,'end'

,'end'

]

很多初學者很疑惑,預設引數是,但是函式似乎每次都「記住了」上次新增了』end』後的 list。

原因解釋如下:

python 函式在定義的時候,預設引數l的值就被計算出來了,即,因為預設引數l也是乙個變數,它指向物件,每次呼叫該函式,如果改變了l的內容,則下次呼叫時,預設引數的內容就變了,不再是函式定義時的了。

定義預設引數要牢記一點:預設引數必須指向不變物件!

要修改上面的例子,我們可以用none這個不變物件來實現:

def

add_end

(l=none):

if l is

none

: l =

'end'

)return l

現在,無論呼叫多少次,都不會有問題:

>>

> add_end()[

'end'

]>>

> add_end()[

'end'

]

如果想要把乙個序列複製幾份然後再拼接起來,可以把這個序列乘乙個整數,這個操作會產生乙個新序列:

>>

> l =[1

,2,3

]>>

> l *3[

1,2,

3,1,

2,3,

1,2,

3]

如果在a * n這個語句中,序列 a 裡的元素是對其他可變物件的引用的話,你就需要格外注意了,因為這個式子的結果可能會出乎意料。比如,你想用my_list = * 3來初始化乙個由列表組成的列表,但是你得到的列表裡包含的 3 個元素其實是 3 個引用,而且這 3 個引用指向的都是同乙個列表。這可能不是你想要的結果。

下面來看看如何初始化乙個由列表組成的列表。`

# 示例:乙個包含3個列表的列表,巢狀的3個列表各自有3個元素來代表井字遊戲的一行方塊

>>

> board =[[

'_']*3

for i in

range(3

)]>>

> board[[

'_',

'_',

'_'],[

'_',

'_',

'_'],[

'_',

'_',

'_']

]>>

> board[1]

[2]=

'x'>>

> board[[

'_',

'_',

'_'],[

'_',

'_',

'x'],[

'_',

'_',

'_']

]# 等價於下面這種寫法

>>

> board =

>>

>

for i in

range(3

):..

. row =

['_']*

3...

..>>

> board[[

'_',

'_',

'_'],[

'_',

'_',

'_'],[

'_',

'_',

'_']

]>>

> board[2]

[0]=

'x'>>

> board[[

'_',

'_',

'_'],[

'_',

'_',

'_'],[

'x',

'_',

'_']

]

下面展示了另乙個方法,這個方法看上去是個誘人的捷徑,但實際上它是錯的。

>>

> weird_board =[[

'_']*3

]*3>>

> weird_board[[

'_',

'_',

'_'],[

'_',

'_',

'_'],[

'_',

'_',

'_']

]>>

> weird_board[1]

[2]=

'o'>>

> weird_board[[

'_',

'_',

'o'],[

'_',

'_',

'o'],[

'_',

'_',

'o']

]# 等價於下面這種寫法

>>

> row =

['_']*

3>>

> board =

>>

>

for i in

range(3

):..

含有 3 個指向同一物件的引用的列表是毫無用處的。

當我們不做修改的時候,看起來都還好。一旦我們試圖標記第 1 行第 2 列的元素,就立馬暴露了列表內的 3 個引用指向同乙個物件的事實。

Python可變序列中的一些坑

聽說面試官比較喜歡這些坑。函式預設引數可變 預設引數有個最大的坑,演示如下 先定義乙個函式,傳入乙個 list,新增乙個end再返回 def add end l end return l當你正常呼叫時,結果似乎不錯 add end 1 2,3 1 2,3 end add end x y z x y ...

python 遇到的一些坑

lst 1,2,4 print lst.iter next 列印出來的是 1 print lst.iter next 列印出來的是 1 呼叫 iter 方法的時候,生成乙個迭代器物件 如上,第二次呼叫,先生成物件,然後返回的是該物件的第乙個值 第二次和第一次列印的是兩個不同的例項的next 方法,但...

UITableView中的一些坑

注意1 如果想從stroyboard中載入靜態 必須把這兩個方法實現去掉,否則顯示不出來資料,且靜態 只能在uitableviewcontroller中實現 pragma mark table view data source nsinteger numberofsectionsintablevie...