4

Lets say I have:

[obj for (_, obj) in stack]

This code assumes that the first object in stack is a tuple, and throws away the first part of the tuple.

What happens if the code is not a tuple, but a single object?

Does it just ignore the thrown-away part and take the whole object?

Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
Richard Garfield
  • 455
  • 1
  • 5
  • 13
  • 4
    If your stack does not consist of sequences or iterables of 2 items, you will get an exception. – Ilja Everilä Mar 30 '16 at 17:07
  • 1
    Note that `_` does not do anything special (outside of the REPL). It's just another variable name. There's nothing being thrown away. – Vincent Savard Mar 30 '16 at 17:07
  • In case you want to read more on the purpose of `_`: http://stackoverflow.com/questions/5893163/what-is-the-purpose-of-the-single-underscore-variable-in-python – Reti43 Mar 30 '16 at 17:11

3 Answers3

6

_ it's just a convention, any other name will behave same way.

Name _ simply points to first element of unpacked tuple. When that name goes out of scope reference, counter is decreased, there are no other named referencing to "first element of unpacked tuple", and that object may be safely garbage-collected.

Since _ is only convention, attempt to unpack tuple with _ will behave same as with any other name - it'll raise an exception, one of following:

a, b = 1  # TypeError: 'int' object is not iterable
a, b = () # ValueError: need more than 0 values to unpack
a, b = (1, 2, 3) # ValueError: too many values to unpack
Łukasz Rogalski
  • 22,092
  • 8
  • 59
  • 93
3

No, it will raise an exception.

>>> _, obj = [0]
ValueError: need more than 1 value to unpack

Using _ is just a convention here. It's used for the dev reading the code ("Oh, he means that variable isn't going to be used for anything"). But for the interpreter, it means nothing in this context and it may as well have been any other identifier name.


What happens if the code is not a tuple, but a single object?

This is something that was improved in python3, where you have this new option available:

>>> *_, obj = [0]
>>> _
[]
>>> obj
0

Unpacking the "last" object will now still work, instead of raising exception, no matter if you have 1, 2, or 3+ items in the container.

wim
  • 338,267
  • 99
  • 616
  • 750
  • Exactly the same idea, but `_, obj = [1, 2, 3]` raises ValueError with a slightly different message. – Reti43 Mar 30 '16 at 17:09
  • 1
    To expound, `_` is used as a variable name when the value of said variable is unneeded. For example, if you want to print "Hi" five times, you might use `for _ in range(5): print 'Hi'` since you don't need the index value. – Jared Goguen Mar 30 '16 at 17:10
0

What you use in your for-loop is called iterable-unpacking, that means any iterable is unpacked to variable names:

a, b, c, ... = iterable

The number of variables on the left side must match the items in the iterable on the right side.

If the number is not equal, a ValueError is raised, if the right side is not iterable, a TypeError is raised.

In your for loop you only use the second argument, per convention unused variables are named _.

Daniel
  • 42,087
  • 4
  • 55
  • 81