python列表中的不连续切片
我正在寻找一种有效的方法来实现这一点,我认为这是类似切片的操作:
>>> mylist = range(100)
>>>magicslicer(mylist, 10, 20)
[0,1,2,3,4,5,6,7,8,9,30,31,32,33,34,35,36,37,38,39,60,61,62,63......,97,98,99]
想法是:切片获取 10 个元素,然后跳过 20 个元素,然后获取下一个 10 个元素,然后跳过接下来的 20 个,依此类推。
我认为如果可能的话我不应该使用循环,因为使用切片的原因(我猜)是为了在单个操作中有效地进行“提取”。
感谢您的阅读。
I'm looking for an efficient way of achieving this, which I think is a slicing-like operation:
>>> mylist = range(100)
>>>magicslicer(mylist, 10, 20)
[0,1,2,3,4,5,6,7,8,9,30,31,32,33,34,35,36,37,38,39,60,61,62,63......,97,98,99]
the idea is: the slicing gets 10 elements, then skips 20 elements, then gets next 10, then skips next 20, and so on.
I think I should not use loops if possible, for the very reason to use slice is (I guess) to do the "extraction" efficiently in a single operation.
Thanks for reading.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
但我得到了一个列表:(
but i obtain a list of list :(
结果
result
[x for x in range(100) if x%30 < 10]
是另一种方法。但是,随着列表大小的增长,这可能会很慢。同一行上的函数
[x for x in range(100) if x%30 < 10]
is another way to do it. But, this can be slow as the list size grows.A function on the same lines
itertools.compress
(2.7/3.1 中的新功能)很好地支持这样的用例,特别是与itertools.cycle
结合使用时:Python 2.7 计时(相对于 Sven 的显式列表理解) ):
Python 3.2 计时(也相对于 Sven 的显式列表理解):
可以看出,相对于 2.7 中的内联列表理解,它并没有太大区别,但通过避免开销,在 3.2 中提供了显着帮助隐式嵌套范围。
如果目标是迭代结果序列而不是将其转换为完全实现的列表,则在 2.7 中也可以看到类似的差异:
对于特别长的模式,可以将模式表达式中的列表替换为 < code>chain(repeat(True, 10), Repeat(False, 20)) 这样就不必在内存中完全创建它。
itertools.compress
(new in 2.7/3.1) nicely supports use cases like this one, especially when combined withitertools.cycle
:Python 2.7 timing (relative to Sven's explicit list comprehension):
Python 3.2 timing (also relative to Sven's explicit list comprehension):
As can be seen, it doesn't make a great deal of difference relative to the in-line list comprehension in 2.7, but helps significantly in 3.2 by avoiding the overhead of the implicit nested scope.
A similar difference can also be seen in 2.7 if the aim is to iterate over the resulting sequence rather than turn it into a fully realised list:
For especially long patterns, it is possible to replace the list in the pattern expression with an expression like
chain(repeat(True, 10), repeat(False, 20))
so that it never has to be fully created in memory.也许最好的方法是直接的方法:
我认为你无法避免循环。
编辑:由于它被标记为“性能”,因此这里与
a = range(100)
的模解进行比较:Maybe the best way is the straight-forward approach:
I don't think you can avoid the loops.
Edit: Since this is tagged "performance", here a comparison with the modulo solution for
a = range(100)
:不幸的是,我认为切片无法做到这一点。我会使用 列表推导式 解决问题
I think that slices cannot do it, unfortunately. I'd solve the problem using list comprehensions
我不知道你是否只使用数字,但如果你坚持使用 numpy,有一种更快的方法。但是,只有当您的列表由展平的相同长度的子列表组成时,以下内容才有效。
用于比较:
I don't know if you are working with numbers only, but in case you are there is a faster way if you stick to numpy. But the following will only work if you have list that consists of sublists of equal length that were flattened out.
For comparison:
我会使用一个循环:
I'd use a loop: