代码之家  ›  专栏  ›  技术社区  ›  user8445949

为什么在Python中对不同类型进行反转和排序?

  •  39
  • user8445949  · 技术社区  · 8 年前

    reversed

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

    sorted

    >>> type(sorted)
    <class 'builtin_function_or_method'>
    

    然而,它们在性质上似乎是相同的。除去功能上的明显差异(反转序列与排序序列),实现上的差异是什么原因?

    2 回复  |  直到 8 年前
        1
  •  53
  •   MSeifert    8 年前

    区别在于 reversed sorted

    所有内置迭代器(至少在python-3.x中)类似 map , zip filter , 颠倒的 , ... 实施为 . 而热切的操作内置是 功能 ,例如。 min , max any all 已排序

    >>> a = [1,2,3,4]
    >>> r = reversed(a)
    <list_reverseiterator at 0x2187afa0240>
    

    实际上,您需要“使用”迭代器来获取值(例如。 list ):

    >>> list(r)
    [4, 3, 2, 1]
    

    功能 已排序

    >>> s = sorted(a)
    [1, 2, 3, 4]
    

    在评论中被问及 为什么这些被实现为类而不是函数

    使用延迟评估操作有一个巨大的好处:当链接时,它们非常节省内存。除非明确“请求”,否则它们不需要创建中间列表。这就是为什么 地图 , 拉链 从急切的操作函数(python-2.x)更改为懒惰的操作类(python-3.x)。

    • return self 在他们的 __iter__
    • 生成器函数-包含 yield

    然而(至少是CPython)用C实现了它们的所有内置模块(和几个标准库模块)。用C创建迭代器类非常容易,但我还没有找到任何合理的方法来创建基于Python-C-API的生成器函数。因此,这些迭代器被实现为类(在CPython中)的原因可能只是方便或缺乏(快速或可实现的)替代方案。

    使用类而不是生成器还有另外一个原因:可以为类实现特殊方法,但不能在生成器函数上实现它们。这听起来可能并不令人印象深刻,但它有一定的优势。例如,大多数迭代器可以是 pickled (至少在Python-3.x上)使用 __reduce__ __setstate__ 方法。这意味着您可以将它们存储在磁盘上,并允许复制它们。由于Python-3.4,一些迭代器也实现了 __length_hint__ (和类似的)要快得多。


    请注意 颠倒的 可以轻松实现工厂功能(如 iter )但不同于 ,可以返回 课程, 只能返回 一个独特的

    __iter__ 而且没有 __reversed__ 方法but是可iterable和反向iterable(通过实现 __getitem__ __len__ ):

    class A(object):
        def __init__(self, vals):
            self.vals = vals
    
        def __len__(self):
            return len(self.vals)
    
        def __getitem__(self, idx):
            return self.vals[idx]
    

    虽然在以下情况下添加抽象层(工厂函数)是有意义的: -因为返回的类取决于输入参数的数量:

    >>> iter(A([1,2,3]))
    <iterator at 0x2187afaed68>
    >>> iter(min, 0)   # actually this is a useless example, just here to see what it returns
    <callable_iterator at 0x1333879bdd8>
    

    这种推理不适用于 :

    >>> reversed(A([1,2,3]))
    <reversed at 0x2187afaec50>
    
        2
  •  4
  •   cs95 abhishek58g    8 年前

    两者的区别是什么 reversed sorted ?

    已排序

    打开REPL会话并键入 help(reversed)

    class reversed(object)
     |  reversed(sequence) -> reverse iterator over values of the sequence
     |  
     |  Return a reverse iterator
    

    它确实是一个用于返回反向迭代器的类。

    好吧,那么 不是函数。但为什么不呢?

    class .