创建时反转列表 [英] Reverse the list while creation

查看:62
本文介绍了创建时反转列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有此代码:

def iterate_through_list_1(arr):
    lala = None
    for i in range(len(arr))[::-1]:
        lala = i

def iterate_through_list_2(arr):
    lala = None
    for i in range(len(arr), 0, -1):
        lala = i

从逻辑上讲,以相反的顺序遍历由range()创建的列表应该比使用range()创建列表并随后使用[::-1]反转列表更有效.但是 cProfile 告诉我,iterate_through_list_1函数的运行速度更快.

Logically, iterating through list created by range() in reverse order should be more efficient, than creating list with range() and reversing it afterwards with [::-1]. But cProfile tells me, that iterate_through_list_1 function works faster.

我使用了python-3.在这里,您可以看到两个相同的数组中包含100000000个元素的配置文件的输出.

I used python-3. And here you can see output of profiling on the two identical arrays with 100000000 elements in them.

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   1    5.029    5.029    5.029    5.029    bs.py:24(iterate_throgh_list_2)
   1    4.842    4.842    4.842    4.842    bs.py:19(iterate_throgh_list_1)

在创建列表时Python切片下面发生了什么?

What happened underneath Python slices while list creation?

推荐答案

精心设计的测试表明,第一个函数在Python 2.x上运行速度最慢(主要是因为必须创建两个列表,第一个列表是递增范围,第二个列表是递增列表)作为还原的第一个).我还包括了一个使用reversed的演示.

Well designed test shows that first function is slowest on Python 2.x (mostly because two lists have to be created, first one as a increasing range, second one as a reverted first one). I also included a demo using reversed.

from __future__ import print_function
import sys
import timeit

def iterate_through_list_1(arr):
    lala = None
    for i in range(len(arr))[::-1]:
        lala = i

def iterate_through_list_2(arr):
    lala = None
    for i in range(len(arr), 0, -1):
        lala = i

def correct_iterate_reversed(arr):
    lala = None
    for obj in reversed(arr):
        lala = obj


print(sys.version)
print('iterate_through_list_1', timeit.timeit('iterate_through_list_1(seq)',
                                              setup='from __main__ import iterate_through_list_1\nseq = range(0, 10000)',
                                              number=10000))
print('iterate_through_list_2', timeit.timeit('iterate_through_list_2(seq)',
                                              setup='from __main__ import iterate_through_list_2\nseq = range(0, 10000)',
                                              number=10000))
print('correct_iterate_reversed', timeit.timeit('correct_iterate_reversed(seq)',
                                                setup='from __main__ import correct_iterate_reversed\nseq = range(0, 10000)',
                                                number=10000))

结果:

2.7.12 (default, Jun 29 2016, 14:05:02) 
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)]
iterate_through_list_1 3.87919592857
iterate_through_list_2 3.38339591026
correct_iterate_reversed 2.78083491325

3.x中的差异都是可以忽略的,因为在每种情况下,迭代的对象都是惰性的.

Differences in 3.x are all neglible, because in each case objects iterated over are lazy.

3.5.2 (default, Jul 28 2016, 21:28:00) 
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)]
iterate_through_list_1 2.986786328998278
iterate_through_list_2 2.9836046030031866
correct_iterate_reversed 2.9411962590020266

这篇关于创建时反转列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆