【问题标题】:Why does Python have `reversed`?为什么 Python 有`reversed`?
【发布时间】:2014-11-18 02:45:56
【问题描述】:

为什么Python有内置函数reversed

为什么不直接使用x[::-1] 而不是reversed(x)


编辑@TanveerAlam pointed out reversed 实际上不是一个函数,而是一个类,尽管在页面@987654323 上列出@

【问题讨论】:

  • 问吉多?他会知道的。
  • for x in my_list[::-1] 太丑了。
  • x[::-1] 的效率远低于reversed(x);它创建了一个全新的列表,而 reversed() 只是创建了一个反向迭代的迭代器。
  • idk 为什么人们不赞成好问题,这类问题真的很好
  • @Hackaholic,我不同意。 “为什么 X 有 Y?”本质上需要对公开可用的电子邮件档案(关于创作者的意图)或第一手知识(即决定出现在 StackOverflow 上的人)进行研究,以获得客观和事实的答案;否则是猜测和意见,这是题外话。现在,“Y 有什么 X 没有的好处?”这是一个很好的问题,但这是一个不同的问题,如果这是本意,那么这就是应该问的问题。

标签: python language-design


【解决方案1】:
>>> a= [1,2,3,4,5,6,7,8,9,10]
>>> a[::-1]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> reversed(a)
<listreverseiterator object at 0x10dbf5390>

第一个符号是急切地生成反向;第二个是给你一个反向迭代器,它可能更便宜,因为它有可能只根据需要生成元素

【讨论】:

    【解决方案2】:

    reversed 返回一个反向迭代器。

    [::-1] 向对象请求切片

    Python 对象尝试返回您可能期望的内容

    >>> [1, 2, 3][::-1]
    [3, 2, 1]
    >>> "123"[::-1]
    '321'
    

    这很方便 - 特别是对于字符串和元组。

    但请记住,大多数代码不需要反转字符串。

    reversed() 最重要的作用是使代码更易于阅读和理解

    它返回一个迭代器而不创建新序列的事实是次要的

    From the docs

    PEP 322:反向迭代一个新的内置函数 reversed(seq)(), 接受一个序列并返回一个遍历元素的迭代器 以相反的顺序排列。

    >>>
    >>> for i in reversed(xrange(1,4)):
    ...    print i
    ...
    3
    2
    1
    

    相比于扩展切片,比如range(1,4)[::-1],reversed()是 更易于阅读、运行速度更快并且使用的内存大大减少。

    注意 reversed() 只接受序列,而不接受任意迭代器。 如果要反转迭代器,请先将其转换为列表 列表()。

    >>>
    >>> input = open('/etc/passwd', 'r')
    >>> for line in reversed(list(input)):
    ...   print line
    ...
    

    【讨论】:

      【解决方案3】:

      reversed 返回一个反向迭代器。

      x[::-1] 返回一个列表。

      In [1]: aaa = [1,2,3,4,5]
      
      In [4]: aaa[::-1]
      Out[4]: [5, 4, 3, 2, 1]
      
      In [5]: timeit(aaa[::-1])
      1000000 loops, best of 3: 206 ns per loop
      
      In [6]: reversed(aaa)
      Out[6]: <listreverseiterator at 0x104310d50>
      
      In [7]: timeit(reversed(aaa))
      10000000 loops, best of 3: 182 ns per loop
      

      【讨论】:

        【解决方案4】:

        首先,reversed 不是内置函数。

        >>> type(reversed)
        <type 'type'>
        

        这是一个遍历序列并给出相反顺序的类。

        试试:

        >>> help(reversed)
        Help on class reversed in module __builtin__:
        
        class reversed(object)
         |  reversed(sequence) -> reverse iterator over values of the sequence
        

        而当我们给它传递一个参数时,它就充当了一个迭代器,

        >>> l = [1, 2, 3, 4]
        >>> obj = reversed(l)
        >>> obj
        <listreverseiterator object at 0x0220F950>
        >>> obj.next()
        4
        >>> obj.next()
        3
        >>> obj.next()
        2
        >>> obj.next()
        1
        >>> obj.next()
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        StopIteration
        

        而切片操作返回整个列表,这对于较大的列表来说内存效率不高。

        这就是为什么在 Python 2 中,我们有 range(它返回整个列表)和 xrange(它在每次迭代中生成每个元素)。

        >>> l[::-1]
        [4, 3, 2, 1]
        

        【讨论】:

        • 我猜这个名为 Built-in Functions 的页面有点误导,因为我现在看到有两个类(reversedzip 等)和函数。
        【解决方案5】:
        aList = [123, 'xyz', 'zara', 'abc', 'xyz'];
        print type(reversed(aList))
        
        bList = [123, 'xyz', 'zara', 'abc', 'xyz'];
        print type(bList[::-1])
        

        输出:

        <type 'listreverseiterator'>
        <type 'list'>
        

        reversed 函数返回一个反向迭代器。 [::-1] 返回一个列表。

        【讨论】:

          【解决方案6】:

          因为 reversed 返回一个迭代器。

          【讨论】:

          • (elem for elem in listOfThings[::-1])也是如此
          • @LegoStormtroopr,是的,但是那个构造了一个倒排列表并对其进行迭代,完全违背了这一点(就内存和性能效率而言)。
          • 我并不是说使用切片更好,但是“返回一个迭代器”并不是它的全部原因,正如其他答案所显示的那样。
          猜你喜欢
          • 2015-08-16
          • 2020-05-17
          • 2014-09-05
          • 1970-01-01
          • 2015-10-02
          • 1970-01-01
          • 2015-04-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多