2

在 python 中,您可以像这样更改列表:

In [303]: x = [1,2,3,4,5,6]

In [304]: x[x <= 3]+=3

In [305]: x
Out[306]: [4, 2, 3, 4, 5, 6]

我已经知道这件事有一段时间了,但我认为我并不完全了解幕后发生的事情。如果有人愿意花时间解释,我会很高兴。

In [307]: x = [1,2,3,4,5,6]

In [308]: dis.dis('x[x <= 3]+=3')
          0 SETUP_LOOP      30811 (to 30814)
          3 SLICE+2        
          4 STORE_SUBSCR   
          5 DELETE_SUBSCR  
          6 SLICE+2        
          7 DELETE_SLICE+1 
          8 FOR_ITER        15659 (to 15670)
         11 DELETE_SLICE+1 

In [309]: x
Out[309]: [1, 2, 3, 4, 5, 6]

In [310]: x[x <= 3]+=3

In [311]: x
Out[311]: [4, 2, 3, 4, 5, 6]

In [312]: x<=3
Out[312]: False

In [313]: x[False]+=3

In [314]: x
Out[314]: [7, 2, 3, 4, 5, 6]
4

1 回答 1

10

x <= 3是一个布尔表达式。由于在 Python 中,boolean类型是 的子类intFalse结果被解释为0,所以最终效果是:

x[0] += 3

或者,以不同的方式展示:

>>> False == 0
True
>>> True == 1
True
>>> isinstance(False, int)
True

dis.dis()方法不适用于字符串;它适用于代码对象(或包含代码的东西,例如函数、方法、类或模块)或字节码。它似乎能够解码您的字符串这一事实是一个快乐的巧合。SETUP_LOOP是操作码 120( 的 ASCII 值x),整个字符串被解释为一组操作码和偏移量。

改用函数:

>>> def foo(): x[x <= 3]+=3
... 
>>> dis.dis(foo)
  1           0 LOAD_GLOBAL              0 (x)
              3 LOAD_GLOBAL              0 (x)
              6 LOAD_CONST               1 (3)
              9 COMPARE_OP               1 (<=)
             12 DUP_TOPX                 2
             15 BINARY_SUBSCR       
             16 LOAD_CONST               1 (3)
             19 INPLACE_ADD         
             20 ROT_THREE           
             21 STORE_SUBSCR        
             22 LOAD_CONST               0 (None)
             25 RETURN_VALUE        
于 2012-10-16T20:17:51.910 回答