列表推导式过程中出现异常的话,中间结果是否保存了?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (57)

当使用try-除了在for循环上下文中,到目前为止执行的命令显然是用

a = [1, 2, 3, 'text', 5]

b = []
try:
    for k in range(len(a)):
        b.append(a[k] + 4)
except:
    print('Error!')
print(b)

结果与

Error!
[5, 6, 7]

然而,对于列表理解而言,情况并非如此。

c=[]
try:
    c = [a[k] + 4 for k in range(len(a))]
except:
    print('Error!')
print(c)

结果是

Error!
[]

在异常发生之前构建的中间列表是否保存在什么地方?可以进入吗?

提问于
用户回答回答于

代码如下:

>>> def example():
...     c=[]
...     try:
...         c = [a[k] + 4 for k in range(len(a))]
...     except:
...         print('Error!')
...     print(c)
... 
>>> import dis
>>> dis.dis(example)

--- removed some instructions       

             27 GET_ITER            
        >>   28 FOR_ITER                20 (to 51)
             31 STORE_FAST               1 (k)
             34 LOAD_GLOBAL              2 (a)
             37 LOAD_FAST                1 (k)
             40 BINARY_SUBSCR       
             41 LOAD_CONST               1 (4)
             44 BINARY_ADD          
             45 LIST_APPEND              2
             48 JUMP_ABSOLUTE           28
        >>   51 STORE_FAST               0 (c)

 --- more instructions...

如您所见,列表推导式被翻译成一系列的指令。GET_ITER...JUMP_ABSOLUTE.下一条指令STORE_FAST是修改c如果在此之前出现任何异常情况,c不会被修改。

用户回答回答于

列表理解中间结果保存在内部的CPython堆栈中,并且不能从作为列表推导式的一部分的Python表达式中访问。

>>> c = 'Anything else'
>>> try:
...     c = [2 // i for i in (1, 0)]
... except ZeroDivisionError:
...     pass
...
>>> c
'Anything else'

在第一个示例中,不生成新的List对象。相反,您可以操纵(使用b.append())现有List对象,这就是为什么您可以看到什么都成功了。b.append()可以调用。

所属标签

可能回答问题的人

  • 爸爸

    腾讯 · 客户端安全 (已认证)

    4 粉丝4 提问5 回答
  • 找虫虫

    0 粉丝0 提问5 回答
  • 不吃貓的鱼oo

    5 粉丝466 提问4 回答
  • uncle_light

    5 粉丝518 提问4 回答

扫码关注云+社区

领取腾讯云代金券