根据list comprehension docthis question:squares = [x**2 for x in range(10)]相当于squares = list(map(lambda x: x**2, range(10)))

但是Python真的通过maplambda实现了列表理解吗?或者文档中的squares = list(map(lambda x: x**2, range(10)))只是近似值,而不是完全等价?

  • 如果是这样,如何处理迭代enumerate个对象?例如,squares = [(idx, x**2) for idx, x in enumerate(range(10))]?我发现很难模仿前面的例子,并用maplambda重写它.

  • 如果不是(我倾向于这个选项,但不确定),列表理解是单独实现的吗?有什么python句子完全等同于列表理解吗?


我的研究成果:

我try 了squares = [print(locals()) for x in range(1)]squares = list(map(lambda x: print(locals()), range(1))),在这个问题eval fails in list comprehension中.第一个得到{'.0': <range_iterator object at 0x000002AB976C4430>, 'x': 0},而后者得到{'x': 0}.也许这表明它们并不完全等价.

我还发现了以下问题:

  1. Where are list comprehensions implemented in CPython source code?
  2. How does List Comprehension exactly work in Python?
  3. List comprehension vs map

他们正在使用Python汇编来显示列表理解的行为.这些答案可能表明列表理解是单独实现的.

所以我倾向于相信maplambda不能实现列表理解.然而,我不确定,我想知道"是否有任何python句子完全等同于列表理解",正如我上面提到的.


这个问题的由来:

我正在努力达到answer a question.我想解释与列表理解相关的奇怪行为,而不使用python汇编.我过go 认为列表理解是通过my previous answer中的lambda实现的.然而,我现在对此表示怀疑.

推荐答案

不,列表理解不是由map和lambda在引擎盖下实现的,也不是在CPython和Pypy3中实现的.

CPython (3.9.13 here) compiles the list comprehension into a special code object that outputs a list并将其作为函数调用:

~ $ echo 'x = [a + 1 for a in [1, 2, 3, 4]]' | python3 -m dis
  1           0 LOAD_CONST               0 (<code object <listcomp> at 0x107446f50, file "<stdin>", line 1>)
              2 LOAD_CONST               1 ('<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_CONST               2 ((1, 2, 3, 4))
              8 GET_ITER
             10 CALL_FUNCTION            1
             12 STORE_NAME               0 (x)
             14 LOAD_CONST               3 (None)
             16 RETURN_VALUE

Disassembly of <code object <listcomp> at 0x107446f50, file "<stdin>", line 1>:
  1           0 BUILD_LIST               0
              2 LOAD_FAST                0 (.0)
        >>    4 FOR_ITER                12 (to 18)
              6 STORE_FAST               1 (a)
              8 LOAD_FAST                1 (a)
             10 LOAD_CONST               0 (1)
             12 BINARY_ADD
             14 LIST_APPEND              2
             16 JUMP_ABSOLUTE            4
        >>   18 RETURN_VALUE

然而,等价的list(map(lambda: ...))件事只是函数调用:

~ $ echo 'x = list(map(lambda a: a + 1, [1, 2, 3, 4]))' | python3 -m dis
  1           0 LOAD_NAME                0 (list)
              2 LOAD_NAME                1 (map)
              4 LOAD_CONST               0 (<code object <lambda> at 0x102701f50, file "<stdin>", line 1>)
              6 LOAD_CONST               1 ('<lambda>')
              8 MAKE_FUNCTION            0
             10 BUILD_LIST               0
             12 LOAD_CONST               2 ((1, 2, 3, 4))
             14 LIST_EXTEND              1
             16 CALL_FUNCTION            2
             18 CALL_FUNCTION            1
             20 STORE_NAME               2 (x)
             22 LOAD_CONST               3 (None)
             24 RETURN_VALUE

Disassembly of <code object <lambda> at 0x102701f50, file "<stdin>", line 1>:
  1           0 LOAD_FAST                0 (a)
              2 LOAD_CONST               1 (1)
              4 BINARY_ADD
              6 RETURN_VALUE

Python相关问答推荐

DataFrame groupby函数从列返回数组而不是值

Pandas实际上如何对基于自定义的索引(integer和非integer)执行索引

使用索引列表列表对列进行切片并获取行方向的向量长度

优化pytorch函数以消除for循环

用合并列替换现有列并重命名

如何根据一列的值有条件地 Select 前N个组,然后按两列分组?

Pandas GroupBy可以分成两个盒子吗?

如何杀死一个进程,我的Python可执行文件以sudo启动?

干燥化与列姆化的比较

巨 Python :逆向猜谜游戏

当条件满足时停止ODE集成?

使用字典或列表的值组合

如何在Django模板中显示串行化器错误

Seaborn散点图使用多个不同的标记而不是点

查找查找表中存在的列值组合

Matplotlib中的曲线箭头样式

有没有一种方法可以根据不同索引集的数组从2D数组的对称子矩阵高效地构造3D数组?

Python:在cmd中添加参数时的语法

Pandas ,快速从词典栏中提取信息到新栏

如何定义一个将类型与接收该类型的参数的可调用进行映射的字典?