Search code examples
pythonpattern-matchingtupleswildcarditerable-unpacking

Wildcards in Python?


Over the years I have noticed the 'wildcard' variable in various bits and pieces of Python I've come across. I assumed it worked like Haskell: allowing you to put a variable where one was required in the formal parameters, but not binding it.

I've used this on, for example, the left hand side of an tuple-unpacking assignment when I don't need one of the variables.

For example:

_, extension = os.path.splitext(filename)

So when I wrote something similar to this today:

(lambda (x,_,_): x)((1,2,3))

I.E. I tried to bind the underscore twice, I received a syntax error. I was surprised to see that _ is indeed a real variable:

(lambda (x,_,z): _)((1,2,3))
> 2

Looks like _ is just a variable name like any other.

Is there a bona fide wildcard variable that I can use as I would like (i.e. able to use more than one in a tuple unpacking assignment), as per the first example?


Solution

  • There is no wildcard variable in Python.

    I try to dissuade people from using _ as a variable name for quite some time now. You are not the first person mistaking _ as some kind of special syntax, so it's better not to use _ as a variable name at all to avoid this kind of confusion. If there ever was a "convention" to use _ as a throw-away variable name, this convention was misguided.

    There are more problems than just the confusion it causes. For example, _ clashes with _ in the interactive interpreter and the common gettext alias.

    Regarding the lambda expression, I'd just use lambda x, *args: ... to ignore all arguments except for the first one. In other cases, I'd use names explicitly stating I don't want to use them, like dummy. In case of loops of range()s, I usually use for i in range(n) and simply don't use i.

    Edit: I just noticed (by looking at the other answers) that you use tuple unpacking in the argument list, so lambda x, *args: ... doesn't solve your problem. Tuple unpacking in parameter lists has been removed in Python 3.x because it was considered too obscure a feature. Better go with mipadi's answer instead.