【问题标题】:[] and list() and 'int' object is not iterable in Python[] 和 list() 和 'int' 对象在 Python 中不可迭代
【发布时间】:2022-01-12 20:26:23
【问题描述】:

假设我有一个整数,我想列出一个列表。

这行得通

[1]

但是,这会导致 'int' 对象不可迭代

list(1)

[]list() 有什么区别,什么时候适合使用?

【问题讨论】:

  • 你给 list() 一个整数而不是一个可迭代的
  • [] 是列表文字的一部分(“列表显示”,技术上)。 list 是一个类,使用list(x) 是调用带有参数x 的列表构造函数,其中x 必须是一个iterable
  • 你已经看到了的不同。 listiterable 作为其参数并创建一个列表,该列表中每个值一个元素。 [...] 要求明确列出每个值。它们不可互换,因此询问何时适合使用它们是没有意义的;您使用真正适合您用例的那个。
  • 这在基本教程和 python 文档中都有介绍,所以我投票关闭作为请求文档。
  • @MadPhysicist 实际上在文档中找到这个并不容易。

标签: python list iterable


【解决方案1】:

它们是完全不同的东西; list 是内置的,[] 是可用于例如列表理解或列表初始化(这是您正在做的)的运算符,也可用于访问容器中的某些索引等. 所以你是在比较苹果和橘子。

list 与生成器表达式和列表解析之间,后者实际上更快:

$ python3 -m timeit '[_ for _ in range(1000)]'
10000 loops, best of 5: 29.4 usec per loop
$ python3 -m timeit 'list(_ for _ in range(1000))'
5000 loops, best of 5: 42.9 usec per loop

如果我们反汇编成字节码,我们会得到:

  • 用于列表理解
>>> dis.dis('[_ for _ in range(10)]')
  1           0 LOAD_CONST               0 (<code object <listcomp> at 0x10d0647c0, file "<dis>", line 1>)
              2 LOAD_CONST               1 ('<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_NAME                0 (range)
              8 LOAD_CONST               2 (10)
             10 CALL_FUNCTION            1
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE

Disassembly of <code object <listcomp> at 0x10d0647c0, file "<dis>", line 1>:
  1           0 BUILD_LIST               0
              2 LOAD_FAST                0 (.0)
        >>    4 FOR_ITER                 8 (to 14)
              6 STORE_FAST               1 (_)
              8 LOAD_FAST                1 (_)
             10 LIST_APPEND              2
             12 JUMP_ABSOLUTE            4
        >>   14 RETURN_VALUE
  • list 加上一个生成器表达式
>>> dis.dis('list(_ for _ in range(10))')
  1           0 LOAD_NAME                0 (list)
              2 LOAD_CONST               0 (<code object <genexpr> at 0x10d0647c0, file "<dis>", line 1>)
              4 LOAD_CONST               1 ('<genexpr>')
              6 MAKE_FUNCTION            0
              8 LOAD_NAME                1 (range)
             10 LOAD_CONST               2 (10)
             12 CALL_FUNCTION            1
             14 GET_ITER
             16 CALL_FUNCTION            1
             18 CALL_FUNCTION            1
             20 RETURN_VALUE

Disassembly of <code object <genexpr> at 0x10d0647c0, file "<dis>", line 1>:
  1           0 LOAD_FAST                0 (.0)
        >>    2 FOR_ITER                10 (to 14)
              4 STORE_FAST               1 (_)
              6 LOAD_FAST                1 (_)
              8 YIELD_VALUE
             10 POP_TOP
             12 JUMP_ABSOLUTE            2
        >>   14 LOAD_CONST               0 (None)
             16 RETURN_VALUE

因此,除了必须查找名称(listLOAD_NAME)之外,它似乎主要取决于内部设计;生成器表达式正在弹出表示堆栈。


将此与您所做的比较:

>>> dis.dis('[1]')
  1           0 LOAD_CONST               0 (1)
              2 BUILD_LIST               1
              4 RETURN_VALUE
>>> dis.dis('list(1)')
  1           0 LOAD_NAME                0 (list)
              2 LOAD_CONST               0 (1)
              4 CALL_FUNCTION            1
              6 RETURN_VALUE

第一个构建一个列表,而第二个是(在查找名称之后)尝试调用函数list(实际上是一个可变序列类型类)。

【讨论】:

  • [] 并不是真正的操作员
  • 我的意思是 [] 都是运营商,但也许我用错了术语
【解决方案2】:

list() 采用 Iterable(例如:setdicttuple 的实例)作为参数,[] 采用明确的元素列表或 comprehension

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-04
    • 2015-04-14
    • 2022-07-01
    • 2015-04-06
    • 2013-10-31
    • 1970-01-01
    • 2016-02-24
    相关资源
    最近更新 更多