如何将 None 插入到列表中?
How to insert None into a list?
运行
L = [1,2,3,4,5,6]
print zip(L,L[1:])[::2]
yields
[(1, 2), (3, 4), (5, 6)]
将生成什么 zip(或其他)语句
[1, 2, None, 3, 4, None, 5, 6, None]
?
更新
开始就可以了
L = [(1,2),(3,4),(5,6)]
只要声明保持(快速)单行。
更新2
插入 None 的一个用例是 plot segments quickly。
一个简单的生成器就可以了:
>>> def insert_none(iterable):
... itr = iter(iterable)
... while True:
... yield next(itr)
... yield next(itr)
... yield None
...
>>> list(insert_none([1, 2, 3, 4, 5, 6]))
[1, 2, None, 3, 4, None, 5, 6, None]
>>> list(insert_none([1, 2, 3, 4, 5]))
[1, 2, None, 3, 4, None, 5]
你可以这样做:
>>> L = [1,2,3,4,5,6]
>>> it = zip(*[iter(L)] * 2)
>>> [y for x in it for y in x + (None,)]
[1, 2, None, 3, 4, None, 5, 6, None]
性能和 space 复杂性 @mgilson 的方法如果稍微修改是最好的方法:
>>> from itertools import izip, chain
>>> L = [1,2,3,4,5,6]*10**5
>>> %timeit [y for x in zip(*[iter(L)] * 2) for y in x + (None, )]
10 loops, best of 3: 47.2 ms per loop
如果我们删除列表推导式并使用 itertools.chain.from_iterable
那么您会发现有显着的改进:
>>> %timeit list(chain.from_iterable(x + (None,) for x in izip(*[iter(L)] * 2)))
10 loops, best of 3: 31.8 ms per loop
>>> %timeit list(insert_none_while(L)) # mgilson's approach
10 loops, best of 3: 50.7 ms per loop
>>> %timeit list(insert_none_for(L))
10 loops, best of 3: 32.6 ms per loop
这里insert_none_while
是@mgilson的原始代码,insert_none_for
是:
def insert_none_for(iterable):
it = iter(iterable)
for x in it:
yield x
yield next(it)
yield None
更新
@Padraic Cunningham 提出的解决方案的略微修改版本似乎是最快的(与 itertools.izip
一起使用时与@Jochen Ritzel 解决方案相比仅略有差距):
>>> L = [1,2,3,4,5,6]*10**6
>>> %timeit [y for x in zip(*[iter(L)] * 2) for y in x + (None, )]
1 loops, best of 3: 541 ms per loop
>>> %timeit list(chain.from_iterable(x + (None,) for x in izip(*[iter(L)] * 2)))
1 loops, best of 3: 349 ms per loop
# Using while 1 and cached next function
>>> %timeit list(insert_none_while_one(L))
1 loops, best of 3: 470 ms per loop
# Cached next function
>>> %timeit list(insert_none_for(L))
1 loops, best of 3: 351 ms per loop
# Jochen Ritzel's original solutions
>>> %timeit it = iter(L); list(itertools.chain.from_iterable(zip(it, it, repeat(None))))
1 loops, best of 3: 352 ms per loop
# Jochen Ritzel's solutions using izip
>>> %timeit it = iter(L); list(itertools.chain.from_iterable(izip(it, it, repeat(None))))
10 loops, best of 3: 167 ms per loop
# Padraic Cunningham's solution using slicing
>>> %timeit list(chain.from_iterable(izip_longest(L[::2],L[1::2],[None])))
1 loops, best of 3: 236 ms per loop
# Padraic Cunningham's solution using iter
>>> %timeit it=iter(L); list(chain.from_iterable(izip_longest(it, it, [])))
10 loops, best of 3: 156 ms per loop
# Kasra
>>> %timeit list(chain(*[L[i:i+2]+[None] for i in range(0,len(L),2)]))
1 loops, best of 3: 1.43 s per loop
还是不够好?
考虑使用 NumPy 数组:
>>> arr = np.array(L, dtype=float)
>>> arr.size
6000000
>>> %timeit np.insert(arr.reshape(-1, 2), 2, None, axis=1).ravel()
10 loops, best of 3: 80.8 ms per loop
相关:How does zip(*[iter(s)]*n)
work in Python?
out = []
for x in xrange(0,len(L)-1,2):
out += L[x:x+2] + [None]
[1, 2, None, 3, 4, None, 5, 6, None]
from itertools import chain,izip
L = [1,2,3,4,5,6]
print(list(chain.from_iterable((x + (None,) for x in izip(L[::2],L[1::2])))))
[1, 2, None, 3, 4, None, 5, 6, None]
您可以使用izip_longest,它会用None
填充缺失值,如果列表非常大,您可以不调用列表进行迭代,避免一次性全部读入内存:
from itertools import izip_longest
print(list(chain.from_iterable(izip_longest(L[::2],L[1::2],[None]))))
[1, 2, None, 3, 4, None, 5, 6, None]
正如@ashwini 指出的那样,结合 iter
它变得更加高效:
it=iter(L)
list(chain.from_iterable(izip_longest(it, it, [])))
zip
接受任意多的参数。 itertools.repeat(None)
给你无限的东西:
import itertools
L = [1,2,3,4,5,6]
it = iter(L)
nons = itertools.repeat(None)
pairs = zip(it,it,nons)
另一个开始很简单:
L = [(1,2),(3,4),(5,6)]
pairs = [(a,b,None) for a,b in L]
要展平元组列表:
flat = itertools.chain.from_iterable(pairs)
作为替代方案,只需使用 chain
:
>>> list(chain(*[L[i:i+2]+[None] for i in range(0,len(L),2)]))
[1, 2, None, 3, 4, None, 5, 6, None]
在没有任何额外导入的情况下,不那么认真地尝试在此任务中赢得代码高尔夫。在 Python 2 和 3 上的工作方式类似。免责声明:这很可能不是最快的 :)
L = [1,2,3,4,5,6]
R = list(sum(zip(*[iter(L)]*2+[iter([].sort,0)]),()))
print(R)
编辑:实际上这是更短的,虽然不是 kludgey:
R = list(sum(zip(*[iter(L)]*2+[[None]*len(L)]),()))
打印:
[1, 2, None, 3, 4, None, 5, 6, None]
另一个使用列表切片的奇特方法
L = [1,2,3,4,5,6]
R = [None] * (len(L) * 3 // 2)
R[::3] = L[::2]
R[1::3] = L[1::2]
print(R)
或者只插入 None
s:
L = [1,2,3,4,5,6]
[ L.insert(i, None) for i in range(2, len(L) * 3 // 2, 3) ]
print(L)
运行
L = [1,2,3,4,5,6]
print zip(L,L[1:])[::2]
yields
[(1, 2), (3, 4), (5, 6)]
将生成什么 zip(或其他)语句
[1, 2, None, 3, 4, None, 5, 6, None]
?
更新
开始就可以了
L = [(1,2),(3,4),(5,6)]
只要声明保持(快速)单行。
更新2
插入 None 的一个用例是 plot segments quickly。
一个简单的生成器就可以了:
>>> def insert_none(iterable):
... itr = iter(iterable)
... while True:
... yield next(itr)
... yield next(itr)
... yield None
...
>>> list(insert_none([1, 2, 3, 4, 5, 6]))
[1, 2, None, 3, 4, None, 5, 6, None]
>>> list(insert_none([1, 2, 3, 4, 5]))
[1, 2, None, 3, 4, None, 5]
你可以这样做:
>>> L = [1,2,3,4,5,6]
>>> it = zip(*[iter(L)] * 2)
>>> [y for x in it for y in x + (None,)]
[1, 2, None, 3, 4, None, 5, 6, None]
性能和 space 复杂性 @mgilson 的方法如果稍微修改是最好的方法:
>>> from itertools import izip, chain
>>> L = [1,2,3,4,5,6]*10**5
>>> %timeit [y for x in zip(*[iter(L)] * 2) for y in x + (None, )]
10 loops, best of 3: 47.2 ms per loop
如果我们删除列表推导式并使用 itertools.chain.from_iterable
那么您会发现有显着的改进:
>>> %timeit list(chain.from_iterable(x + (None,) for x in izip(*[iter(L)] * 2)))
10 loops, best of 3: 31.8 ms per loop
>>> %timeit list(insert_none_while(L)) # mgilson's approach
10 loops, best of 3: 50.7 ms per loop
>>> %timeit list(insert_none_for(L))
10 loops, best of 3: 32.6 ms per loop
这里insert_none_while
是@mgilson的原始代码,insert_none_for
是:
def insert_none_for(iterable):
it = iter(iterable)
for x in it:
yield x
yield next(it)
yield None
更新
@Padraic Cunningham 提出的解决方案的略微修改版本似乎是最快的(与 itertools.izip
一起使用时与@Jochen Ritzel 解决方案相比仅略有差距):
>>> L = [1,2,3,4,5,6]*10**6
>>> %timeit [y for x in zip(*[iter(L)] * 2) for y in x + (None, )]
1 loops, best of 3: 541 ms per loop
>>> %timeit list(chain.from_iterable(x + (None,) for x in izip(*[iter(L)] * 2)))
1 loops, best of 3: 349 ms per loop
# Using while 1 and cached next function
>>> %timeit list(insert_none_while_one(L))
1 loops, best of 3: 470 ms per loop
# Cached next function
>>> %timeit list(insert_none_for(L))
1 loops, best of 3: 351 ms per loop
# Jochen Ritzel's original solutions
>>> %timeit it = iter(L); list(itertools.chain.from_iterable(zip(it, it, repeat(None))))
1 loops, best of 3: 352 ms per loop
# Jochen Ritzel's solutions using izip
>>> %timeit it = iter(L); list(itertools.chain.from_iterable(izip(it, it, repeat(None))))
10 loops, best of 3: 167 ms per loop
# Padraic Cunningham's solution using slicing
>>> %timeit list(chain.from_iterable(izip_longest(L[::2],L[1::2],[None])))
1 loops, best of 3: 236 ms per loop
# Padraic Cunningham's solution using iter
>>> %timeit it=iter(L); list(chain.from_iterable(izip_longest(it, it, [])))
10 loops, best of 3: 156 ms per loop
# Kasra
>>> %timeit list(chain(*[L[i:i+2]+[None] for i in range(0,len(L),2)]))
1 loops, best of 3: 1.43 s per loop
还是不够好?
考虑使用 NumPy 数组:
>>> arr = np.array(L, dtype=float)
>>> arr.size
6000000
>>> %timeit np.insert(arr.reshape(-1, 2), 2, None, axis=1).ravel()
10 loops, best of 3: 80.8 ms per loop
相关:How does zip(*[iter(s)]*n)
work in Python?
out = []
for x in xrange(0,len(L)-1,2):
out += L[x:x+2] + [None]
[1, 2, None, 3, 4, None, 5, 6, None]
from itertools import chain,izip
L = [1,2,3,4,5,6]
print(list(chain.from_iterable((x + (None,) for x in izip(L[::2],L[1::2])))))
[1, 2, None, 3, 4, None, 5, 6, None]
您可以使用izip_longest,它会用None
填充缺失值,如果列表非常大,您可以不调用列表进行迭代,避免一次性全部读入内存:
from itertools import izip_longest
print(list(chain.from_iterable(izip_longest(L[::2],L[1::2],[None]))))
[1, 2, None, 3, 4, None, 5, 6, None]
正如@ashwini 指出的那样,结合 iter
它变得更加高效:
it=iter(L)
list(chain.from_iterable(izip_longest(it, it, [])))
zip
接受任意多的参数。 itertools.repeat(None)
给你无限的东西:
import itertools
L = [1,2,3,4,5,6]
it = iter(L)
nons = itertools.repeat(None)
pairs = zip(it,it,nons)
另一个开始很简单:
L = [(1,2),(3,4),(5,6)]
pairs = [(a,b,None) for a,b in L]
要展平元组列表:
flat = itertools.chain.from_iterable(pairs)
作为替代方案,只需使用 chain
:
>>> list(chain(*[L[i:i+2]+[None] for i in range(0,len(L),2)]))
[1, 2, None, 3, 4, None, 5, 6, None]
在没有任何额外导入的情况下,不那么认真地尝试在此任务中赢得代码高尔夫。在 Python 2 和 3 上的工作方式类似。免责声明:这很可能不是最快的 :)
L = [1,2,3,4,5,6]
R = list(sum(zip(*[iter(L)]*2+[iter([].sort,0)]),()))
print(R)
编辑:实际上这是更短的,虽然不是 kludgey:
R = list(sum(zip(*[iter(L)]*2+[[None]*len(L)]),()))
打印:
[1, 2, None, 3, 4, None, 5, 6, None]
另一个使用列表切片的奇特方法
L = [1,2,3,4,5,6]
R = [None] * (len(L) * 3 // 2)
R[::3] = L[::2]
R[1::3] = L[1::2]
print(R)
或者只插入 None
s:
L = [1,2,3,4,5,6]
[ L.insert(i, None) for i in range(2, len(L) * 3 // 2, 3) ]
print(L)