【问题标题】:Creating a list in Python- something sneaky going on?在 Python 中创建一个列表——发生了什么鬼鬼祟祟的事情?
【发布时间】:2011-02-13 18:25:42
【问题描述】:

抱歉,如果这没有任何意义,我对 Python 很陌生!

通过在解释器中的测试,我可以看到 list()[] 都产生一个空列表:

>>> list()
[]
>>> []
[]

根据我目前了解到的情况,创建对象的唯一方法是调用它的构造函数 (__init__),但是当我只输入 [] 时,我看不到这种情况发生。那么通过执行[],Python 是否会将其映射到对list() 的调用?

【问题讨论】:

    标签: python list constructor


    【解决方案1】:

    使用 list() 和 [] 的主要区别是什么?

    list() 和 [] 之间最明显和最明显的关键区别在于语法。暂时先把语法搁置一旁,那些刚接触过 Python 的人或中间接触过 Python 的人可能会争辩说它们都是列表或派生自同一个类;那是真实的。这进一步增加了了解两者关键差异的重要性,其中大部分内容概述如下。

    list() 是一个函数,[] 是 字面语法

    让我们看看当我们通过反汇编器分别调用list()和[]时会发生什么。

    >>> import dis
    >>> print(dis.dis(lambda: list()))
      1           0 LOAD_GLOBAL              0 (list)
                  3 CALL_FUNCTION            0 (0 positional, 0 keyword pair)
                  6 RETURN_VALUE
    None
    >>> print(dis.dis(lambda: []))
      1           0 BUILD_LIST               0
                  3 RETURN_VALUE
    None
    

    上面反汇编程序的输出表明,文字语法版本不需要全局查找,由操作码 LOAD_GLOBAL 表示或函数调用,由操作码 CALL_FUNCTION 表示。

    因此,文字语法比对应的语法更快。 – 让我们花点时间看看下面的时间。

    import timeit
    >>> timeit.timeit('[]', number=10**4)
    0.0014592369552701712
    >>> timeit.timeit('list()', number=10**4)
    0.0033833282068371773
    

    另一方面,同样重要且值得指出的是文字语法,[] 不会解包值。解包示例如下所示。

    >>> list('abc') # unpacks value
    ['a', 'b', 'c']
    >>> ['abc'] # value remains packed
    ['abc']
    

    python 中的字面量是什么?

    文字是一种符号或一种编写常量或原始变量值的方式,python 将其识别为内置类型。

    来自我在 PythonRight - what's the difference between list and [] 上的帖子。

    【讨论】:

    • 我觉得这个答案比我在同一主题上看到的其他答案更值得称赞(包括重复问题)
    • 我很高兴你发现它很有用@s​​tormfield。 ?
    【解决方案2】:

    自:

    class list(object):
        """
        list() -> new empty list
        list(iterable) -> new list initialized from iterable's items
        """
    

    如果列表中的元素是iterable(即str),则list()[] 的工作方式不同。

    所以

    >>> a = ['ab']
    >>> b = list('ab')
    >>> a[0]
    'ab'
    >>> b[0]
    'a'
    

    【讨论】:

      【解决方案3】:

      与大多数编程语言一样,Python 有一种称为 literals 的东西,这意味着可以使用特殊语法来写出一些最重要的值类型。这很少是必要的,但它使我们可以更轻松地使用 Python,我们可以编写文字。

      >>> 0
      0
      >>> int()
      0
      >>> 5
      5
      >>> int('5') # I'm using a string literal here though!
      5
      >>> 0.0
      0.0
      >>> float()
      0.0
      >>> "" 
      ''
      >>> str()
      ''
      >>> u""
      u''
      >>> unicode()
      u''
      >>> ()
      ()
      >>> tuple()
      ()
      >>> {}
      {}
      >>> dict()
      {}     
      

      当我们创建自己的类型(类)时,我们使用它们的构造函数创建它们的实例,例如 list 用于列表。当我们使用文字时,它有点像调用list 的语法糖,但实际上它在幕后调用了相同的基本内容。

      【讨论】:

        【解决方案4】:

        除了其他答案,来自Language Reference

        列表显示是方括号中可能为空的一系列表达式:

        list_display        ::=  "[" [expression_list | list_comprehension] "]"
        ...
        

        列表显示会产生一个新的列表对象。

        它没有明确提到“产生一个新的列表对象”是如何实现的。就像您提到的那样,它很可能是对 list() 构造函数的调用。或者,列表非常简单,得到特殊处理,list() 实际上映射到完全不同的东西。

        无论哪种方式,[] 肯定不会映射到对名为 __builtins__.list 的类型的构造函数的调用,因为重新定义该类型仍会导致 [] 返回一个实际列表,正如其他回答者所显示的那样。

        【讨论】:

          【解决方案5】:

          我昨天开始学习python.... 我猜你不得不说它的内部映射

          >>> a = []
          >>> type(a)
          <type 'list'>
          >>> a = list()
          >>> type(a)
          <type 'list'>
          

          【讨论】:

          • +1 在您使用 Python 的第二天深入并回答问题!
          【解决方案6】:

          不,Python 不会调用 list(),或者您可以通过分配给列表来影响 [] 创建的类型,这是您无法做到的:

          >>> import __builtin__
          >>> __builtin__.list = set
          >>> list()
          set([])
          >>> []
          []
          

          [] 是创建列表的语法。它是一种内置类型,并且具有特殊的语法,就像字典、字符串、整数和浮点数以及许多其他类型一样。

          创建类型的实例可以通过调用类型来完成,例如list()——它会依次为您调用类型的构造函数和初始化程序。直接调用初始化程序 (__init__) 并创建该类型的新实例。调用构造函数 (__new__) 可以,但您不应该直接调用它。

          【讨论】:

            【解决方案7】:

            这两种结构的处理方式完全不同:

            >>> import dis
            >>> def f(): return []
            ... 
            >>> dis.dis(f)
              1           0 BUILD_LIST               0
                          3 RETURN_VALUE        
            >>> def f(): return list()
            ... 
            >>> dis.dis(f)
              1           0 LOAD_GLOBAL              0 (list)
                          3 CALL_FUNCTION            0
                          6 RETURN_VALUE        
            >>> 
            

            [] 表单使用操作码BUILD_LIST 构造一个列表,而list() 表单调用list 对象的构造函数。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2022-11-13
              • 1970-01-01
              • 2015-01-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多