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?
Not really. Python is not Haskell. Map, apply, reduce, and lambda are kind of second-class citizens, though there is some interesting stuff in itertools.
Unless you have some need to use one-line lambdas, the correct way is this:
def f(x, *args, **kwargs):
return x
The *args
argument lets you use any number of unnamed arguments (which will be available as a tuple called args
). Extra named arguments will be in a dictionary called kwargs
.
I don't think there's any way to do this in a lambda, but there's usually no need. A function declaration can go anywhere. Note, you do interesting / evil stuff if you put the function definition inside another function (or loop):
def make_func(s):
def f(*trash, **more_trash):
print s
return f
f1 = make_func('hello')
f2 = make_func('world')
f1(1,2,'ham','spam')
f2(1,2,a=1,b=2)
will output:
>>> hello
>>> world
As @rplnt pointed out, this won't be the same for loops:
funcs = []
for s in ('hello','world'):
def f():
print s
funcs.append(f)
for f in funcs:
f()
will output:
>>> world
>>> world
because loops only have one namespace.
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.
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