我有一个列表A
,我希望将元素1,2,11,12,21,22等作为列表。
例如,如果A = range(100)
,那么我想要[0, 1, 10, 11, 20, 21, ..., 90, 91]
现在我有[num for elem in [[A[i], A[i+1]] for i in range(0, len(A)-1, 10)] for num in elem]
是否有更简洁或更有效的方法来实现它?
答案 0 :(得分:3)
如果您只想要配对(如果101不在范围内,则不包括100)请使用itertools.chain
和range
以及zip
(考虑使用xrange
和{ {3}}更大的N
}值:
itertools.chain(*zip(range(0, N, 10), range(1, N, 10)))
或者使用itertools.izip
避免解包:
itertools.chain.from_iterable(zip(range(0, N, 10), range(1, N, 10)))
查看内容:
>>> N = 100
>>> list(itertools.chain(*zip(range(0, N, 10), range(1, N, 10))))
[0, 1, 10, 11, 20, 21, 30, 31, 40, 41, 50, 51, 60, 61, 70, 71, 80, 81, 90, 91]
答案 1 :(得分:3)
使用带enumerate()
的模数运算符来过滤索引。
[elem for idx,elem in enumerate(A) if idx%10 in (0,1)]
答案 2 :(得分:3)
怎么样:
[A[i] for i in xrange(0, len(A)) if i%10 in (0, 1)]
答案 3 :(得分:3)
[elem for i, elem in enumerate(A) if i %10 in (0, 1)]
答案 4 :(得分:3)
使用zip
[i for t in zip(A[::10],A[1::10]) for i in t]
逻辑 - 通过一次跳过10来循环遍历列表中的两个元素,但是从1开始其中一个元素,从0开始另一个元素
使用相同的逻辑,您可以尝试itertools.izip
(对于Py2用户)
from itertools import izip
[i for t in izip(A[::10],A[1::10]) for i in t]
时间 -
zip
$ python -m timeit -s "A = range(100)" "[i for t in zip(A[::10],A[1::10]) for i in t]"
100000 loops, best of 3: 1.98 usec per loop
izip
$ python -m timeit -s "A = range(100);from itertools import izip" "[i for t in izip(A[::10],A[1::10]) for i in t]"
1000000 loops, best of 3: 1.79 usec per loop
比较其他答案
$ python -m timeit -s "A = range(100)" "[elem for idx,elem in enumerate(A) if idx%10 in (0,1)]"
100000 loops, best of 3: 9.39 usec per loop
$ python -m timeit -s "A = range(100)" "[A[i] for i in xrange(0, len(A)) if i%10 in (0, 1)]"
100000 loops, best of 3: 7.92 usec per loop
izip
在这里非常快!
答案 5 :(得分:1)
由于Bhargav Rao采用obvious选择的压缩切片,所以这是一个相当简单的协程,因为filter
只需要两个True
和八个False
要做到这一点:
import itertools # only needed for Python 2
def first_two_of_ten():
x2, x8 = xrange(2), xrange(8) # use range in Python 3
yield # gotta queue up a coroutine to send to it
while True:
for i in x2:
yield True
for i in x8:
yield False
和用法:
ftot = first_two_of_ten()
next(ftot) # gotta queue the coroutine up
的实际使用情况
>>> list(itertools.ifilter(ftot.send, xrange(50)))
[0, 1, 10, 11, 20, 21, 30, 31, 40, 41]
再次,在Python 3中将range
替换为xrange
,并且只使用内置的filter
用于Python 3。