我有一个列表,我想用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