当前位置: 首页 > 面试题库 >

在Python中通过切片进行有效的迭代

董砚
2023-03-14
问题内容

Python中切片操作的迭代效率如何?而且,如果不可避免地要有切片,那么有替代方法吗?

我知道列表上的切片操作为O(k),其中k是切片的大小。

x[5 : 5+k]  # O(k) copy operation

但是,当遍历列表的一部分时,我发现执行此操作的最简洁的方法(也是最Python的?)(不必求助于索引)是:

for elem in x[5 : 5+k]:
  print elem

但是,我的直觉是,这仍然会导致子列表的开销很大,而不是简单地遍历现有列表。


问题答案:

您可以用来itertools.islice从列表中获取切片式迭代器:

例:

>>> from itertools import islice
>>> lis = range(20)
>>> for x in islice(lis, 10, None, 1):
...     print x
...     
10
11
12
13
14
15
16
17
18
19

正如@
user2357112所指出的那样,的性能islice取决于切片的起点和可迭代的大小,在几乎所有情况下,普通切片都将很快,因此应首选。以下是一些时序比较:

对于 巨大的名单 islice是稍快或等于正常片时片的起点是列表中只有不到一半的大小,更大的指标正常切片是明显的赢家。

>>> def func(lis, n):
        it = iter(lis)
        for x in islice(it, n, None, 1):pass
...     
>>> def func1(lis, n):
        #it = iter(lis)
        for x in islice(lis, n, None, 1):pass
...     
>>> def func2(lis, n):
        for x in lis[n:]:pass
...     
>>> lis = range(10**6)

>>> n = 100
>>> %timeit func(lis, n)
10 loops, best of 3: 62.1 ms per loop
>>> %timeit func1(lis, n)
1 loops, best of 3: 60.8 ms per loop
>>> %timeit func2(lis, n)
1 loops, best of 3: 82.8 ms per loop

>>> n = 1000
>>> %timeit func(lis, n)
10 loops, best of 3: 64.4 ms per loop
>>> %timeit func1(lis, n)
1 loops, best of 3: 60.3 ms per loop
>>> %timeit func2(lis, n)
1 loops, best of 3: 85.8 ms per loop

>>> n = 10**4
>>> %timeit func(lis, n)
10 loops, best of 3: 61.4 ms per loop
>>> %timeit func1(lis, n)
10 loops, best of 3: 61 ms per loop
>>> %timeit func2(lis, n)
1 loops, best of 3: 80.8 ms per loop


>>> n = (10**6)/2
>>> %timeit func(lis, n)
10 loops, best of 3: 39.2 ms per loop
>>> %timeit func1(lis, n)
10 loops, best of 3: 39.6 ms per loop
>>> %timeit func2(lis, n)
10 loops, best of 3: 41.5 ms per loop

>>> n = (10**6)-1000
>>> %timeit func(lis, n)
100 loops, best of 3: 18.9 ms per loop
>>> %timeit func1(lis, n)
100 loops, best of 3: 18.8 ms per loop
>>> %timeit func2(lis, n)
10000 loops, best of 3: 50.9 us per loop    #clear winner for large index
>>> %timeit func1(lis, n)

对于 小型列表, 普通切片比islice几乎所有情况下都快。

>>> lis = range(1000)
>>> n = 100
>>> %timeit func(lis, n)
10000 loops, best of 3: 60.7 us per loop
>>> %timeit func1(lis, n)
10000 loops, best of 3: 59.6 us per loop
>>> %timeit func2(lis, n)
10000 loops, best of 3: 59.9 us per loop

>>> n = 500
>>> %timeit func(lis, n)
10000 loops, best of 3: 38.4 us per loop
>>> %timeit func1(lis, n)
10000 loops, best of 3: 33.9 us per loop
>>> %timeit func2(lis, n)
10000 loops, best of 3: 26.6 us per loop

>>> n = 900
>>> %timeit func(lis, n)
10000 loops, best of 3: 20.1 us per loop
>>> %timeit func1(lis, n)
10000 loops, best of 3: 17.2 us per loop
>>> %timeit func2(lis, n)
10000 loops, best of 3: 11.3 us per loop

结论:

去正常切片。



 类似资料:
  • 本文向大家介绍Python进阶之迭代器与迭代器切片教程,包括了Python进阶之迭代器与迭代器切片教程的使用技巧和注意事项,需要的朋友参考一下 在前两篇关于 Python 切片的文章中,我们学习了切片的基础用法、高级用法、使用误区,以及自定义对象如何实现切片用法(相关链接见文末)。本文是切片系列的第三篇,主要内容是迭代器切片。 迭代器是 Python 中独特的一种高级特性,而切片也是一种高级特性,

  • 问题内容: 我有一个这样的对象: 我需要在HTML表中获取ID和名称,但是似乎很难遍历此对象。TIA。我知道我需要先到达“值数组”,然后再到达“组”对象,但是我要遍历对象和数组之间的过渡以及foreach与基于索引的迭代。 例如,我尝试了这个: 它遍历对象,但也给我没用 问题答案:

  • 问题内容: 有没有办法遍历Java SparseArray(适用于Android)?我曾经很容易通过索引来获取值。我找不到一个。 问题答案: 似乎我找到了解决方案。我没有正确注意到该功能。 因此,我将使用以下内容:

  • 问题内容: 我想知道我什么时候做类似的事情 创建新字符串或返回视图/迭代器 问题答案: Python会进行逐个切片,这意味着每次切片时(非常琐碎的切片(例如)除外),它都会将所有数据复制到一个新的字符串对象中。 根据一位开发人员的说法,之所以做出此选择是因为 [按引用切片]方法更复杂,更难实现并且可能导致意外行为。 例如: 使用“按切片复制”设计,可以立即释放字符串。尽管您只对第一个字符感兴趣,但

  • 问题内容: 我正在尝试从json文件中提取嵌套值。我想打印出每个“ id”键的每个值。我想我已经接近了,但无法弄清楚为什么obj类型从字典更改为列表,然后为什么我无法解析该列表。这是我正在使用的json的链接: http //hastebin.com/ratevimixa.tex 这是我当前的代码: -------------------------------------------------

  • 问题内容: 我有一个数据框。 我想选择在所有指数是 不是 在列表中, 现在,我使用列表理解来创建所需的标签以进行切片。 工作正常,但如果我经常需要这样做可能会很笨拙。 有一个更好的方法吗? 问题答案: 在索引上使用并反转布尔索引以执行标签选择:

  • 我在C:drive(本地计算机)中有一个名为abc.xls的excel文件,现在在第一张表本身的excel文件中有一个如下所示的表,这个下面的表可以位于表中的任何范围内,所以我开发了下面的java程序,它将首先按行扫描整个表,然后按列扫描,并将找到TradeRef所在的单元格 下面的程序中的问题是,它捕获TradeRef所在的单元格,然后迭代列,然后以类似的方式捕获下一行并迭代列 但我要应用的逻辑

  • 问题内容: 如何在Go中反转任意切片()?我宁愿不必编写和使用。有没有简单的内置方法来做到这一点? 问题答案: 没有一个简单的,内置的用于反转接口{}的部分。您可以编写一个for循环来做到这一点: Go 1.8中引入的reflect.Swapper函数可用于编写通用的反转函数: 游乐场的例子