这个问题已经在这里有一个答案:
- 查找和列表(蟒)替换元件 8分的答案
我有一个名单,我想用无以取代值,其中条件()返回true。
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
例如,如果条件检查布尔(项目%2)应返回:
[None, 1, None, 3, None, 5, None, 7, None, 9, None]
什么是最有效的方式做到这一点?
这个问题已经在这里有一个答案:
我有一个名单,我想用无以取代值,其中条件()返回true。
[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)的定时展示非timesave:
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
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
只是通过可迭代的(包括调用生成的结果)作为第一个参数,决定断言,如果一个值必须更换为第二ARG,让“呃裂口。
例如:
>>> list(replaceiniter(xrange(11), lambda x: x%2))
[0, None, 2, None, 4, None, 6, None, 8, None, 10]
这里的另一种方式:
>>> L = range (11)
>>> map(lambda x: x if x%2 else None, L)
[None, 1, None, 3, None, 5, None, 7, None, 9, None]
>>> 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]
在你要替换的位值的情况下,您可以通过分配到原来的整片更新您的原始列表与列表理解的值。
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]
注:这是一般倾向于一个比其他(改变列表到位与否)不建议,但行为你应该知道的。
这可能有助于...
test_list = [5, 8]
test_list[0] = None
print test_list
#prints [None, 8]