我有一個列表,我想用None替換值,其中condition()返回True。使用Python替換列表中的值
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
例如,如果條件檢查布爾(項%2)應返回:
[None, 1, None, 3, None, 5, None, 7, None, 9, None]
什麼是最有效的方式做到這一點?
我有一個列表,我想用None替換值,其中condition()返回True。使用Python替換列表中的值
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
例如,如果條件檢查布爾(項%2)應返回:
[None, 1, None, 3, None, 5, None, 7, None, 9, None]
什麼是最有效的方式做到這一點?
建立與列表理解一個新的列表:
new_items = [x if x % 2 else None for x in items]
您可以修改,地方,如果你想在原來的列表,但它實際上並沒有節省時間:
items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for index, item in enumerate(items):
if not (item % 2):
items[index] = None
下面是(Python 3.6.3)演示非時隙的時序:
In [1]: %%timeit
...: items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
...: for index, item in enumerate(items):
...: if not (item % 2):
...: items[index] = None
...:
1.06 µs ± 33.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [2]: %%timeit
...: items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
...: new_items = [x if x % 2 else None for x in items]
...:
891 ns ± 13.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
個
和Python 2.7.6計時:
In [1]: %%timeit
...: items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
...: for index, item in enumerate(items):
...: if not (item % 2):
...: items[index] = None
...:
1000000 loops, best of 3: 1.27 µs per loop
In [2]: %%timeit
...: items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
...: new_items = [x if x % 2 else None for x in items]
...:
1000000 loops, best of 3: 1.14 µs per loop
是最有效的?不枚舉必須創建一個迭代器並形成一個元組,增加開銷? Python列表列表中的列表,給你不斷的時間訪問? – geowa4 2009-10-08 20:05:26
我想,我可能是錯的,他的意思是要返回列表的副本,而不是修改原來的位置。但是,當允許就地修改時提供有效的解決方案仍然+1。 – 2009-10-08 20:07:07
如果我想修改原始位置,是不是也可以使用itertools中的imap? – 2009-10-08 20:19:44
>>> L = range (11)
>>> [ x if x%2 == 1 else None for x in L ]
[None, 1, None, 3, None, 5, None, 7, None, 9, None]
ls = [x if (condition) else None for x in ls]
Riffing上側的問題由OP在評論問,即:
如果我有一臺發電機能產生 值範圍(11)而不是 列表。是否可以取代發生器中的 值?
當然,這是很輕鬆...:
def replaceiniter(it, predicate, replacement=None):
for item in it:
if predicate(item): yield replacement
else: yield item
只是通過可迭代的(包括調用生成的結果)作爲第一個參數,謂詞來決定是否值必須更換作爲第二個參考,讓我們呃裂口。
例如:
>>> list(replaceiniter(xrange(11), lambda x: x%2))
[0, None, 2, None, 4, None, 6, None, 8, None, 10]
+1呵呵......我想學習如何寫這個‘一’行漂亮的蟒蛇解決方案...提示請 – gath 2009-10-09 11:34:37
@gath,我不明白你的問題 - 評論是漂亮的限制,所以你應該打開一個新的問題,所以你可以展開和闡明你要找的是它... – 2009-10-09 15:23:55
這裏的另一種方式:
>>> L = range (11)
>>> map(lambda x: x if x%2 else None, L)
[None, 1, None, 3, None, 5, None, 7, None, 9, None]
這可能有助於...
test_list = [5, 8]
test_list[0] = None
print test_list
#prints [None, 8]
燦你解釋一下你爲什麼認爲這可能有幫助? – 2017-01-14 00:48:09
@ T-Heron它可以被修改以滿足問題的要求 – Emil 2017-01-15 23:24:48
如果它需要*修改*,那麼它不是被問到的問題的答案。請自己作出(或解釋)必要的修改,或刪除答案。 – 2017-08-02 09:55:57
如果你要到位,以取代值,可以 用列表中的值更新您的原始列表 comprehensi通過分配原稿的整個片段。
data = [*range(11)] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
id_before = id(data)
data[:] = [x if x % 2 else None for x in data]
data
# Out: [None, 1, None, 3, None, 5, None, 7, None, 9, None]
id_before == id(data) # check if list is still the same
# Out: True
如果你有指向原來的列表中的多個名稱, 比如你改變列表 以前寫data2=data
,你跳過切片標誌分配到data
, data
將重新綁定到指向新創建而data2
仍指向原來的不變清單。
data = [*range(11)] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
data2 = data
id_before = id(data)
data = [x if x % 2 else None for x in data] # no [:] here
data
# Out: [None, 1, None, 3, None, 5, None, 7, None, 9, None]
id_before == id(data) # check if list is still the same
# Out: False
data2
# Out: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
注:這是一般傾向於一個比其他 (到位變化列表或沒有),但行爲,你應該知道的任何建議。
使用itertools模塊,它是最高效的。 – LtWorf 2016-01-29 14:38:44
對於'在-place'更換比較,看看這個【答案】(http://stackoverflow.com/a/24203748/307454) – lifebalance 2016-11-23 03:12:04