聽說面試官比較喜歡這些坑。
預設引數有個最大的坑,演示如下:
先定義乙個函式,傳入乙個 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...