【问题标题】:What's "better" the reverse method or the reversed built-in function?什么是“更好”的 reverse 方法或 reversed 内置函数?
【发布时间】:2011-07-24 22:00:56
【问题描述】:

什么通常被认为更 Pythonic/更好/更快使用,反向方法或反向内置函数?

两者都在行动:

_list = list(xrange(4))

print _list

rlist = list(reversed(_list))

print rlist

_list.reverse()

print _list

【问题讨论】:

    标签: python list methods reverse built-in


    【解决方案1】:

    foo.reverse() 实际上是反转容器中的元素。 reversed() 实际上并没有反转任何东西,它只是返回一个可用于以相反顺序迭代容器元素的对象。如果这是您需要的,它通常比实际反转元素要快。

    【讨论】:

      【解决方案2】:

      似乎有很大的不同。我真的以为是反过来的。 为什么重新排列列表中的值比从迭代器中创建新值更快?

      from decorators import bench
      
      _list = range(10 ** 6)
      
      @ bench
      def foo():
        list(reversed(_list))
      
      @ bench
      def bar():
        _list.reverse()
      
      foo()
      bar()
      
      print foo.time
      print bar.time
      

      0.167278051376
      0.0122621059418

      【讨论】:

      • 内存分配本身不应该花费太长时间; IIRC 列表是单个连续分配(PyObject**)。更可能的区别是因为list(reversed(_list)),即使list 构造函数是C 代码,也必须通过reverseiterator 的API 而不是仅仅在紧密的C 循环中交换指针。
      • 如果他们必须检查listreverseiterator,那么他们必须检查所有内容......最终它变得有点笨拙,并且减慢了短副本的速度。此外,reversed 的常见情况是您无论如何都要进行迭代并且不需要创建临时的。
      • 如果你对列表做点什么,图片就会改变。比较for i in reversed(_list):..._list.reverse();for i in _list:...前者要快一点。
      【解决方案3】:

      取决于您是否要就地反转列表(即更改列表)。没有其他真正的区别。

      经常使用reversed 会产生更好的代码。

      【讨论】:

        【解决方案4】:

        在不知道有关性能的真实统计信息的情况下,_list.reverse() 会修改列表本身,而 reversed(_list) 返回一个准备好以相反顺序遍历列表的迭代器。这本身就是一个很大的不同。

        如果这不是问题,object.reverse() 对我来说似乎更具可读性,但也许您有特定的速度要求。如果reverse() 不属于消耗资源的软件的 80%,我不会打扰(作为一般经验法则)。

        【讨论】:

        • reversed 不复制,它返回一个迭代器。
        【解决方案5】:
        • _list.reverse() 执行就地反转并且不返回值
        • reversed(_list) 不会改变 _list,而是返回一个反向迭代 对象
        • _list[::-1] 不改变_list,而是返回反转切片

        示例:

        _list = [1,2,3]
        ret1 = list(reversed(_list))
        ret2 = _list[::-1] #reverse order slice
        ret3 = _list.reverse() #no value set in ret3
        print('ret1,ret2,ret3,_list:',ret1,ret2,ret3,_list)
        
        _list = [1,2,3]
        for x in reversed(_list):
            print(x)
        

        输出:

        ret1,ret2,ret3,_list: [3, 2, 1] [3, 2, 1] None [3, 2, 1]
        3
        2
        1
        

        【讨论】:

          【解决方案6】:

          如果您最终要修改迭代器中的列表,使列表不可变并且使用不可变数据总是更好,尤其是在您进行函数式编程时,使用 reversed() 总是更好。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-06-09
            • 2010-10-26
            • 2014-05-03
            • 2014-12-27
            • 2020-07-26
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多