Python is all about writing beautiful code. So, I was running pylint
to check the "beautifulness" of my code, when I bump into something:
Unused variable 'myvar1'
From this part of my code:
for myvar1, myvar2 in mylist:
# Do stuff just using myvar2
mylist
is a list of tuples, so I'm unwrapping the tuples into two variables (myvar1
and myvar2
). I'm defining those two variables just to unwrap the second one, because I don't need the other.
So, here's my question: Is there a way to tell the interpreter to unwrap the tuple, but not assing the first part (for example). In some other languages you can do something like:
for _, myvar in mylist:
# Do stuff with myvar
or
for *, myvar in mylist:
# Do stuff with myvar
That means: I don't care about the first part of the tuple, I just need the second one.
NOTE: I know that this could be an option for what I'm asking:
for mytuple in mylist:
# Do stuff with mytuple[1]
But that's by far less readable.
If you want to unzip your list of tuples, you use the combination of zip() method and * operator.
Unpacking Tuples When we put tuples on both sides of an assignment operator, a tuple unpacking operation takes place. The values on the right are assigned to the variables on the left according to their relative position in each tuple . As you can see in the above example, a will be 1 , b will be 2 , and c will be 3 .
Tuple packing refers to assigning multiple values into a tuple. Tuple unpacking refers to assigning a tuple into multiple variables.
Multiple assignment (also known as tuple unpacking or iterable unpacking) allows you to assign multiple variables at the same time in one line of code. This feature often seems simple after you've learned about it, but it can be tricky to recall multiple assignment when you need it most.
In addition to @RaymondHettinger's answer: Pylint also does not complain about unused variables if their names start with a single underscore. This means that you can use:
for _myvar1, myvar2 in mylist:
getting the best of both worlds:
This works for function / method prototypes too and avoids warnings about unused parameters, which you can often get when deriving from a base class in an OO framework.
Did you try either of these?
for _, myvar in mylist:
#Do stuff
works fine in Python and is relatively idiomatic.
I write for _, myvar2 in mylist
when I want to emphasize that only myvar2 is used.
And I write for myvar1, myvar2 in mylist
when I want to remind the reader (usually me) what the record structure is.
The _
name is just a naming convention for a throw-away value. The CPython interpreter makes the variable assignment for it just like it would with any other variable name (fortunately, *STORE_FAST* is a very cheap operation). In contrast, the PyPy interpreter will identify the unused variable assignment as dead code, so you get the optimization for free regardless of how you write it.
If you're curious about how CPython interprets your code, the dis module can provide useful insights:
>>> 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
As the other posters have mentioned, the warnings from pylint can sometimes be inane. If you prefer a short variable name in your code, then just ignore the pylint complaint. As Francis Avila pointed out, pylint should't complain about _
in this context.
I suppose you could do this:
for myvar in (t[1] for t in mylist):
pass
But frankly I think you should just ignore the pylint warning in this case--it's beautiful enough and won't cause any confusion (which is why you want to beauty in the first place).
I would say Python is all about writing readable code - any "beauty" is merely a side-effect.
The first item of the tuple could be eliminated like this:
for myvar2 in zip(*mylist)[1]:
# Do stuff with myvar2
But I'm not sure I'd really recommend it. Personally I would just use:
for myvar1, myvar2 in mylist:
# Do stuff with myvar2
... and ignore pylint.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With