很常见的模式是遍历列表的一部分并搜索/选择/处理项目:
for item in array[start:end]:
# do something
据我所知,这将从array[start:end]
复制项创建一个新列表,遍历它,然后临时列表被垃圾收集。这看起来像是浪费CPU的使用。你知道吗
使用itertools.islice可以解决这个问题。你知道吗
问:为什么这不是经常使用和教导像是教导危险的可变默认函数参数等。?你知道吗
更新:
正如在评论中指出的,“itertools.islice
代表iterables,而不是list。在到达第n个元素之前,它必须迭代很多次”。你知道吗
我想islice
不是一个好例子,但是创建一个临时列表来遍历它是一个存在的问题。不是吗?
你可以做:
for i in xrange(start, end):
item = array[i]
# do something with the item
有没有一种pythonic方法可以迭代序列的一部分而不创建它的副本?。因为本例中不支持负索引,而且它不像for item in sequence
那么好。你知道吗
切片之所以是Pythonic,即使它创建了一个副本,是因为切片的成本通常是微不足道的宏伟计划的事情。如果从
list
中切片10000个项目,只需迭代并丢弃它们,其成本是:在C级,相对于解释器本身的开销而言,分配几KB的RAM和递增/递减几千个整数是相当微不足道的(请记住,无论您做什么,当您循环并将每个元素存储在一个命名变量中时,引用计数都会更新);几乎任何你用结果
list
做的事情都会比创建和销毁它的成本更高,特别是在切片很小的情况下(用任何替换它的解释器开销可能会超过切片的成本)。你知道吗如果拷贝确实是个问题,而且
start
索引非常重要(因此islice
无法直接跳到start
点使得它不可行,并且片足够大,您可以合理地担心内存),那么我所知的最Pythonic的方法基本上就是您提供的示例循环:如果速度太慢(重复索引会在CPython引用解释器中产生惊人的解释器开销),那么最适合python的方法就是将索引推到C层:
这避免了临时的
list
,以换取更高的每元素成本(因为索引无法完全避免,只是隐藏在C层,不涉及字节码执行)。当然,Pythonic的程度要低一些(map
通常是不受欢迎的,而明确地引用像__getitem__
这样的特殊方法是非常难看的)。你知道吗相关问题 更多 >
编程相关推荐