Pythonic方法返回列表中的每一个第n项

假设我们有一个从0到1000的数字列表。是否有一个pythonic /高效的方式来产生第一个和每个后续的第10个项目,即[0, 10, 20, 30, ... ]

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

 >>> l = range(165) >>> l[0::10] [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160] 

编辑:只是为了好玩,有点时间比较(忽略边界条件):

 $ python -m timeit -s "l = range(1000)" "l1 = [x for x in l if x % 10 == 0]" 1000 loops, best of 3: 525 usec per loop $ python -m timeit -s "l = range(1000)" "l1 = l[0::10]" 100000 loops, best of 3: 4.02 usec per loop 
  1. source_list[::10]是最明显的,但是这对任何迭代都不起作用,对于大型列表来说不是有效的内存。
  2. itertools.islice(source_sequence, 0, None, 10)适用于任何迭代,并且是高效的,但可能不是大列表和大步骤的最快解决scheme。
  3. (source_list[i] for i in xrange(0, len(source_list), 10))

你可以像这样使用切片运算符:

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

s[i:j:k] slice of s from i to j with step k手册: s[i:j:k] slice of s from i to j with step k

 li = range(100) sub = li[0::10] >>> sub [0, 10, 20, 30, 40, 50, 60, 70, 80, 90] 
 newlist = oldlist[::10] 

这挑出列表的每10个元素。

为什么不使用范围函数的步骤参数来获得:

 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 

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

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

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

 existing_list = range(0, 1001) filtered_list = [i for i in existing_list if i % 10 == 0] 

列表parsing正是为此而做的:

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

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