假设我们有一个从0到1000的数字列表。是否有一种python式的/有效的方法来生成第一个和后续的第10项的列表,即[0,10,20,30,…]] ?

是的,我可以使用for循环来做到这一点,但我想知道是否有一种更整洁的方法来做到这一点,也许甚至在一行中?


当前回答

为什么不直接使用range函数的阶跃参数,得到:

l = range(0, 1000, 10)

为了进行比较,在我的机器上:

H:\>python -m timeit -s "l = range(1000)" "l1 = [x for x in l if x % 10 == 0]"
10000 loops, best of 3: 90.8 usec per loop
H:\>python -m timeit -s "l = range(1000)" "l1 = l[0::10]"
1000000 loops, best of 3: 0.861 usec per loop
H:\>python -m timeit -s "l = range(0, 1000, 10)"
100000000 loops, best of 3: 0.0172 usec per loop

其他回答

你可以像这样使用切片操作符:

l = [1,2,3,4,5]
l2 = l[::2] # get subsequent 2nd item

为什么不直接使用range函数的阶跃参数,得到:

l = range(0, 1000, 10)

为了进行比较,在我的机器上:

H:\>python -m timeit -s "l = range(1000)" "l1 = [x for x in l if x % 10 == 0]"
10000 loops, best of 3: 90.8 usec per loop
H:\>python -m timeit -s "l = range(1000)" "l1 = l[0::10]"
1000000 loops, best of 3: 0.861 usec per loop
H:\>python -m timeit -s "l = range(0, 1000, 10)"
100000000 loops, best of 3: 0.0172 usec per loop

列表推导式正是为此而设计的:

smaller_list = [x for x in range(100001) if x % 10 == 0]

你可以在python官方文档中获得更多信息: http://docs.python.org/tutorial/datastructures.html#list-comprehensions

下面是一个“每10个项目”列表理解的更好实现,它不使用列表内容作为成员测试的一部分:

>>> l = range(165)
>>> [ item for i,item in enumerate(l) if i%10==0 ]
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
>>> l = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
>>> [ item for i,item in enumerate(l) if i%10==0 ]
['A', 'K', 'U']

但是这仍然比仅仅使用列表切片要慢得多。

使用范围(start, end, step)

li = list(range(0, 1000, 10))

[0, 10, 20, 30, 40, 50, 60, 70, 80, 90 ... 990]

或者,如果你有一个列表,使用slice: From manual: s[i:j:k] slice of s From i to j, step k

yourlist = [0, ... ,10 ...]  
sub = yourlist[::10]  # same as yourlist[0:100:10]

>>> sub
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]