Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在列表中插入无?_Python_Performance_List_Python 2.7 - Fatal编程技术网

Python 如何在列表中插入无?

Python 如何在列表中插入无?,python,performance,list,python-2.7,Python,Performance,List,Python 2.7,运行 zip(或其他)语句会产生什么结果 [(1, 2), (3, 4), (5, 6)] ? 更新 一开始就很好 [1, 2, None, 3, 4, None, 5, 6, None] 只要声明保持(快速)一行 更新2 插入None的一个用例是。一个简单的生成器可以: L = [(1,2),(3,4),(5,6)] 您可以这样做: >>> def insert_none(iterable): ... itr = iter(iterable) ... whil

运行

zip(或其他)语句会产生什么结果

[(1, 2), (3, 4), (5, 6)]
?

更新

一开始就很好

[1, 2, None, 3, 4, None, 5, 6, None]
只要声明保持(快速)一行

更新2


插入None的一个用例是。

一个简单的生成器可以:

L = [(1,2),(3,4),(5,6)]

您可以这样做:

>>> 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]
性能和空间复杂度方面@mgilson的方法(如果稍加修改)是最好的:

>>> 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]
如果我们删除列表理解并从_iterable中使用
itertools.chain

>>> 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
此处
insert\u none\u而
是@mgilson的原始代码,
insert\u none\u for
是:

>>> %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

更新 @Padraic Cunningham提出的解决方案的一个稍加修改的版本似乎是最快的(与@Jochen Ritzel解决方案结合使用
itertools.izip
)相比,仅略有差距):


还不够好吗?

考虑使用NumPy阵列:

>>> 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

相关的:

您可以使用izip_longest,它将用
None
填充缺少的值,如果列表非常大,您可以在不调用列表的情况下进行迭代,避免一次将所有内容读入内存:

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]
正如@ashwini所指出的,与
iter
相结合会变得更加有效:

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]

zip
接受任意数量的参数
itertools.repeat(None)
为您提供无限量的零:

it=iter(L)
list(chain.from_iterable(izip_longest(it, it, [])))
另一个起点很简单:

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)

在这项任务中,在没有任何额外导入的情况下,不太认真地尝试赢得代码高尔夫。在Python2和Python3上的工作方式类似。免责声明:这可能不是最快的:)

编辑:事实上,这是较短的,但没有那么笨拙:

L = [1,2,3,4,5,6]
R = list(sum(zip(*[iter(L)]*2+[iter([].sort,0)]),()))
print(R)
印刷品:

R = list(sum(zip(*[iter(L)]*2+[[None]*len(L)]),()))
另一个花式的使用列表切片

[1, 2, None, 3, 4, None, 5, 6, None]
或者只需插入
None
s:

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)

什么映射到这里的什么?为什么你关心它是否是一条直线?这是Python。如果从
L=[1,2,3,4,5]
开始,您想要什么?(例如,长度不能被2整除)@mgilson让我们假设它是一个先决条件,即它是不可预测的,具有奇数len()。。只有两个问题。你能补充一个简短的解释吗?如果我很大的话,每行的速度会有多快?我只是想发布这个。。。请不要到处打我几秒钟Ashwini:)@JonClements——从时间戳上看,好像是3分钟;-)。。。FWIW,我想发布类似的东西。
zip(*[iter(…)]
已经足够有名了,但是将它与嵌套的理解相结合。。。我不知道。似乎有点多:-)。嗯。。。有趣的是
应该比真正的
执行得更好。我假设
while True
循环有一大堆额外的条件检查,尽管这似乎是python应该能够优化的常见情况(例如跳过检查)。@mgilson一个问题是
True
在Python2中每次都是全局查找的,
而1
可能会稍微加快它的速度。再加上循环中每次对
next()
POP\u JUMP\u IF\u FALSE
的额外调用。如果L很大,你确定这足够快吗?如果
L
很大,这可能是最好的答案。它不会像您需要制作切片以传递到
zip
时那样创建任何中间列表。如果L很大,则循环中的迭代速度受解释器速度的限制,因此这是不够的。这不对吗?@calaf,itertools解决方案应该是有效的,长度不均匀的列表会发生什么情况?+1但是,切片很昂贵。我们应该用迭代器替换它:
it=iter(L);列表(chain.from_iterable(izip_longest(it,it,[]))))
。注意,默认的fillvalue已经是
None
,所以作为第三个参数的空列表也应该这样做。在我的系统上12毫秒,我们有一个赢家。;-)@AshwiniChaudhary,我只是在里面放了一个,因为我认为这会让事情变得更加明显,
iter(L)
很整洁,但是我的系统没有获得太多的性能提升?是的,时间方面的差异不会太大(特别是对于中小型列表),但是使用切片我们在内存中创建了两个额外的列表。因此,使用
iter()
可以节省时间和内存。对于更大的列表,差异是显而易见的,对于
len(L)
=6000000,差异是233毫秒与156毫秒。您最好结束它——OP希望它平坦
itertools.chain.from_iterable(zip(it,it,nons))
:-)但打印[(a,b,None)对于a,b在L]中产生[(1,2,None),(3,4,None),(5,6,None)]。@mgilson:for
L=[1,2,3,4,5]
列表(chain.from_iterable(izip(it,it,repeat(None,len(L‘‘‘)’)
产生
[1,2,None,3,4,None],/zip>
(it,it,nons)做得很好。@mgilson:更好,不过现在我需要一个解释:(@Jan PhilipGehrcke——这让我来谈谈我对这个问题的看法。如果长度不能被2整除,会发生什么?我很确定所有基于zip的答案都会截断一个值,这就是我使用基于生成器的方法的原因:-)
iter([].sort,0)
…这可能是我见过的所有
None
函数中最复杂的一种。Genius。想不出任何短函数会返回None:(
L = [1,2,3,4,5,6]
R = list(sum(zip(*[iter(L)]*2+[iter([].sort,0)]),()))
print(R)
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)
L = [1,2,3,4,5,6]
[ L.insert(i, None) for i in range(2, len(L) * 3 // 2, 3) ]
print(L)