解包元组/列表时的多余部分
Python的核心就是写出优美的代码。所以,我在用pylint
来检查我的代码是否优美时,遇到了一些问题:
未使用的变量 'myvar1'
这是我代码中的一部分:
for myvar1, myvar2 in mylist:
# Do stuff just using myvar2
mylist
是一个包含元组的列表,所以我把元组拆解成两个变量(myvar1
和myvar2
)。我定义这两个变量只是为了提取第二个,因为我并不需要第一个。
所以,我的问题是:有没有办法告诉解释器只拆解元组,但不赋值给第一个部分(例如)。在其他一些语言中,你可以这样做:
for _, myvar in mylist:
# Do stuff with myvar
或者
for *, myvar in mylist:
# Do stuff with myvar
这意味着:我不关心元组的第一部分,我只需要第二部分。
注意:我知道这可能是我所问的一个选项:
for mytuple in mylist:
# Do stuff with mytuple[1]
但这样写可读性差得多。
6 个回答
你试过这两个方法吗?
for _, myvar in mylist:
#Do stuff
在Python中运行得很好,而且用法也比较符合常规。
我在写 for _, myvar2 in mylist
时,是想强调只有 myvar2 这个变量会被用到。
而我写 for myvar1, myvar2 in mylist
时,是想提醒读者(通常是我自己)这个记录的结构是什么样的。
这里的 _
只是一个命名习惯,用来表示一个不需要的值。CPython 解释器会像处理其他变量名一样处理这个变量的赋值(幸运的是,*STORE_FAST* 这个操作是非常便宜的)。相比之下,PyPy 解释器 会把这个未使用的变量赋值识别为无效代码,因此无论你怎么写,它都会自动优化。
如果你对 CPython 如何解释你的代码感兴趣,可以使用 dis 模块 来获取一些有用的信息:
>>> from dis import dis
>>> def f(lot):
for _, var2 in lot:
print var2
>>> dis(f)
2 0 SETUP_LOOP 25 (to 28)
3 LOAD_FAST 0 (lot)
6 GET_ITER
>> 7 FOR_ITER 17 (to 27)
10 UNPACK_SEQUENCE 2
13 STORE_FAST 1 (_)
16 STORE_FAST 2 (var2)
3 19 LOAD_FAST 2 (var2)
22 PRINT_ITEM
23 PRINT_NEWLINE
24 JUMP_ABSOLUTE 7
>> 27 POP_BLOCK
>> 28 LOAD_CONST 0 (None)
31 RETURN_VALUE
正如其他人提到的,pylint 的警告有时候可能很无聊。如果你喜欢在代码中使用短的变量名,那就忽略 pylint 的抱怨吧。正如 Francis Avila 指出的那样,在这种情况下,pylint 不应该对 _
提出警告。
除了@RaymondHettinger的回答之外:Pylint不会对以单个下划线开头的未使用变量发出警告。这意味着你可以使用:
for _myvar1, myvar2 in mylist:
这样你就能得到两全其美的效果:
- 没有Pylint的警告,
- 同时还能获取记录结构的信息
这个方法同样适用于函数或方法的原型,能够避免关于未使用参数的警告,这种警告在面向对象的框架中从基类派生时经常会出现。