我有一個列表:mylist = [0, 0, 0, 0, 0]
更換出現選擇列表中的元素在Python
我只希望替換選擇的元素,比方說第一,第二,和一個共同的數量,A = 100
第四。要做到這一點
方式一:
mylist[:2] = [A]*2
mylist[3] = A
mylist
[100, 100, 0, 100, 0]
我要尋找一個班輪,或者更簡單的方法來做到這一點。更普遍和靈活的答案是可取的。
我有一個列表:mylist = [0, 0, 0, 0, 0]
更換出現選擇列表中的元素在Python
我只希望替換選擇的元素,比方說第一,第二,和一個共同的數量,A = 100
第四。要做到這一點
方式一:
mylist[:2] = [A]*2
mylist[3] = A
mylist
[100, 100, 0, 100, 0]
我要尋找一個班輪,或者更簡單的方法來做到這一點。更普遍和靈活的答案是可取的。
特別是因爲您要更換的一個相當大的塊list
,我會做這個不可改變:
mylist = [100 if i in (0, 1, 3) else e for i, e in enumerate(mylist)]
這是故意在Python這使得新list
是一個班輪,而變異的一個list
需要一個顯式循環。通常,如果你不知道你想要哪一個,你需要新的list
。 (在某些情況下,它更慢或更復雜,或者你有一些其他代碼引用了相同的list
,並需要看到它發生了變異,或者其他,這就是爲什麼這是「通常」而不是「始終」。)
如果你想要做一次這樣多,我包起來的功能,如波動說明:
def elements_replaced(lst, new_element, indices):
return [new_element if i in indices else e for i, e in enumerate(lst)]
我個人很可能會使其成爲一個發電機,因此產生一個迭代的,而不是返回一個列表,即使我永遠不會需要這個,只是因爲我這樣愚蠢。但是,如果你真的做需要它:
myiter = (100 if i in (0, 1, 3) else e for i, e in enumerate(mylist))
或者:
def elements_replaced(lst, new_element, indices):
for i, e in enumerate(lst):
if i in indices:
yield new_element
else:
yield e
這是你在找什麼?列出要更改的索引,然後遍歷該列表以更改值。
els_to_replace = [0, 1, 3]
mylist = [0, 0, 0, 0, 0]
for index in els_to_replace:
mylist[index] = 100
mylist
Out[9]: [100, 100, 0, 100, 0]
def replace_element(lst, new_element, indices):
for i in indices:
lst[i] = new_element
return lst
這絕對是一個更通用的解決方案,而不是一個班輪雖然。例如,你的情況,你會打電話:
mylist = replace_element(mylist, 100, [0, 1, 3])
+1。除了更普遍之外,我認爲這是做可變替換的最可讀的方式,儘管(或者可能是因爲)不是單線程的。 – abarnert
numpy的支持這一點,如果你不反對使用np.ndarray
:
>>> a = np.zeros(5)
>>> a[[0,1,3]] = 100
>>> a
array([ 100., 100., 0., 100., 0.])
+1。即使這並不直接回答OP的問題(我不確定它沒有),但是每當你發現自己處理數字序列並且看起來比應該更難時,你應該問的第一個問題可能是「我是否反對在這裏使用'np.ndarray'?」 – abarnert
不是這一個巨大的風扇,但你可以試試這個(雖然我覺得所有上述得多簡潔易讀):從可疑的可讀性
In [22]: from operator import setitem
In [23]: mylist = [0, 0, 0, 0, 0]
In [24]: indeces_to_replace = [0, 1, 3]
In [25]: _ = map(lambda x: setitem(mylist, x, 100), indeces_to_replace)
In [26]: mylist
Out[26]: [100, 100, 0, 100, 0]
一邊,需要進口,@abarnert指出了一些額外的問題,即map
仍會創建一個不必要的列表(該列表會被_
丟棄,但會被創建),並且它不能在Python 3中工作,因爲Python 3.x中的map
returns an iterator。您可以使用six模塊來模擬Python 2中Python 3.x中map
的行爲。x以及與collections.deque
(再次按照@abarnert的建議)結合使用時,可以在不創建內存中的附加列表的情況下實現相同的輸出,因爲可包含最多0
項目將放棄從迭代器map
收到的所有內容(注意six
,map
通過使用itertools.imap
來模擬)。
同樣,也完全沒有必要永遠使用這個 - 高於/低於每一個解決方案是更好:)
In [1]: from collections import deque
In [2]: from six.moves import map
In [3]: from operator import setitem
In [4]: mylist = [0, 0, 0, 0, 0]
In [5]: indeces_to_replace = [0, 1, 3]
In [6]: deque(map(lambda x: setitem(mylist, x, 100), indeces_to_replace), maxlen=0)
Out[6]: deque([], maxlen=0)
In [7]: mylist
Out[7]: [100, 100, 0, 100, 0]
主要與此相關的問題是,在Python 3中,它不起作用,因爲您只需取回一個永遠不會迭代的迭代器。較小的問題是,在Python 2中,它構建了一個你不需要的列表。你可以通過明確地執行list(map(...))來解決第一個問題。或者你可以通過使用'six.map'並將結果傳遞給一個'iter_discard'函數來解決這兩個問題,你可以將它作爲'collections.deque(it,max_size = 0)'來實現。這是一個更多的想法,你應該把它放在一個解決方案,你不是一個巨大的粉絲,當然... – abarnert
@abarnert遲到+1到你的答案(一如既往的信息),和偉大的觀點關於這個實現(從未考慮過將'map'的結果傳遞給'iter_discard'函數)。我會爲後人的緣故添加一個更新,並且一如既往地感謝有用的信息:) – RocketDonkey
我真的希望'iter_discard'是3.x標準庫的一部分。反對它的觀點是,這將鼓勵人們使用'map'來代替結果(而且,如果你真的想要,'deque'技巧已經被添加到'itertools'文檔的某處)。我可以買那個......但是對於這些問題,人們總是這樣做(然後想用他們可以找到的每個Python版本來「計時」結果)。 – abarnert
我喜歡列表理解:
[100 if index in [1, 4] else 0 for index, x in enumerate(mylist) ]
這個怎麼樣? mylist [:2],mylist [3] = [A] * 2,A –