2012-04-02 160 views
4

我在考慮內置Python List方法時遇到問題。Python LIST函數不返回新列表

當我學習Python時,我一直認爲Python的mutators,因爲任何值類的mutators都應該做的,返回它創建的新變量。

拿這個例子:

a = range(5) 
# will give [0, 1, 2, 3, 4] 
b = a.remove(1) 
# as I learned it, b should now be [0, 2, 3, 4] 
# what actually happens: 
# a = [0, 2, 3, 4] 
# b = None 

的主要問題與此列表突變沒有返回一個新的列表,就是你不能將多個突變之後。 說,我想從0到5的名單,而2和3 存取器返回新的變量應該是能夠做到這一點是這樣的:

a = range(5).remove(2).remove(3) 

這可悲的是不可能的,因爲range(5).remove(2) = None

現在,有沒有一種方法可以在列表中實際做多個突變,就像我想在我的例子中做的那樣?我認爲即使PHP允許這些類型的字符串隨後的突變。

我也無法找到所有內置Python函數的很好的參考。如果任何人都可以找到所有列表mutator方法的實際定義(包含返回值),請告訴我。我所能找到的只是這個頁面:http://docs.python.org/tutorial/datastructures.html

+1

首先,你要查找的文檔http://docs.python.org/library/stdtypes.html#mutable-sequence-types – 2012-04-02 20:23:16

+0

「當我瞭解到的Python,我一直以爲Python的改變者,就像任何值類的mutators應該做的一樣,返回它創建的新變量。「 - 你在哪裏學習?事實上,在Python中擁有可變狀態的對象是非常常見的,而列表就是其中之一。 (字符串不是) – millimoose 2012-04-02 20:39:18

回答

9

不是變異並返回對象,Python庫選擇只有一種方法來使用mutator的結果。從import this

應該有一個 - 最好只有一個 - 明顯的方法來做到這一點。

說了這麼多,你想要做什麼,更普通的Python風格是使用列表理解生成器表達式

[x for x in range(5) if x != 2 and x != 3] 

你也可以連接這些結合在一起:

>>> [x for x in (x for x in range(5) if x != 2) if x != 3] 
[0, 1, 4] 

上述生成器表達式具有額外的優勢,它在O(n)時間,因爲Python僅迭代range()一次。對於大型發電機的表達式,甚至對於無限的發電機表達式,這是有利的。

+1

嗯,我想在使用列表來排除它時可以很方便地執行如下操作:'[x for x在範圍內(5)如果不是在(2,3)中的x)'' – 2012-04-02 23:13:40

2

Python或php都沒有內置的「mutators」。你可以簡單地寫多行,像

a = list(range(5)) 
a.remove(2) 
a.remove(3) 

如果你想生成一個新的列表,複印留存老一:

a = list(range(5)) 
b = a[:] 
b.remove(2) 

注意,在大多數情況下,remove奇異調用指示你應該首先使用set

+2

只有在Python 3中才需要調用'list'。 – agf 2012-04-02 20:25:10

+0

'set'與'list'有什麼不同? – 2012-04-03 08:40:41

+0

@stevenroose如果你想通過它的值去除一個特定的元素,那麼set將具有O(log n)或者那個操作的O(1)性能。通常,列表的性能將在O(n)左右。 – phihag 2012-04-03 09:18:37

4

list和其他可變類型的許多方法故意返回None,這樣您就不會懷疑是創建新對象還是改變現有對象。唯一可能發生的是變異,因爲如果創建了一個新對象,它必須由該方法返回,並且不會返回。

您可能已經注意到,編輯字符串的str的方法會返回新字符串,因爲字符串是不可變的,並且總是返回一個新字符串。

有當然什麼都沒有耽誤你寫一個list子類,具有所期望的行爲.append()等,雖然這似乎是相當重錘僅僅擺動,讓您鏈方法調用。此外,大多數Python程序員不會期望這種行爲,使您的代碼不太清晰。

-1

要刪除列表上的多個突變,只要你想在你的例子做,你可以這樣做:

a = range(5) 
a = [i for j, i in enumerate(a) if j not in [2, 3]] 

一會[0,1,4]

+1

一個註釋:'list.remove(x)'方法刪除值爲「x」的項目,而不是您的腳本執行的索引「x」處的項目。對於執行相同操作的'range()'列表,它可能不會做正確的事情;} – 2012-04-03 08:42:58

4

在Python中,基本上所有使對象變異的方法都返回None

這樣你就不會意外地認爲你有一個新的對象。

你提到

我想即使PHP允許這些類型的字符串隨後的突變。

雖然我不記得PHP,用字符串操作,你可以方法調用,因爲字符串是不可變,所以所有的字符串方法返回一個新的字符串,因爲它們不(不能)改變你打電話給他們的人。

>>> "a{0}b".format(3).center(5).capitalize().join('ABC').swapcase() 
'a A3B b A3B c'