假设我们有一个从0到1000的数字列表。是否有一种python式的/有效的方法来生成第一个和后续的第10项的列表,即[0,10,20,30,…]] ?
是的,我可以使用for循环来做到这一点,但我想知道是否有一种更整洁的方法来做到这一点,也许甚至在一行中?
假设我们有一个从0到1000的数字列表。是否有一种python式的/有效的方法来生成第一个和后续的第10项的列表,即[0,10,20,30,…]] ?
是的,我可以使用for循环来做到这一点,但我想知道是否有一种更整洁的方法来做到这一点,也许甚至在一行中?
当前回答
Source_list[::10]是最明显的,但这对任何可迭代对象都不起作用,对于大型列表内存效率也不高。 itertools。islice(source_sequence, 0, None, 10)适用于任何可迭代对象,并且是内存高效的,但对于大列表和大步骤可能不是最快的解决方案。 (source_list[i] for i in xrange(0, len(source_list), 10))
其他回答
existing_list = range(0, 1001)
filtered_list = [i for i in existing_list if i % 10 == 0]
>>> lst = list(range(165))
>>> lst[0::10]
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
注意,这比循环检查每个元素的模量快100倍左右:
$ python -m timeit -s "lst = list(range(1000))" "lst1 = [x for x in lst if x % 10 == 0]"
1000 loops, best of 3: 525 usec per loop
$ python -m timeit -s "lst = list(range(1000))" "lst1 = lst[0::10]"
100000 loops, best of 3: 4.02 usec per loop
下面是一个“每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']
但是这仍然比仅仅使用列表切片要慢得多。
列表推导式正是为此而设计的:
smaller_list = [x for x in range(100001) if x % 10 == 0]
你可以在python官方文档中获得更多信息: http://docs.python.org/tutorial/datastructures.html#list-comprehensions
你可以像这样使用切片操作符:
l = [1,2,3,4,5]
l2 = l[::2] # get subsequent 2nd item