89

I am running Eclipse SDK v3.6 with PyDev v2.6 plugin on two PC, with Linux and Windows.

I would like to pass a tuple as an argument, like:

foo = lambda (x,y): (y,x)
print (foo((1,2)))

This works on Linux and gives the correct result:

> (2,1)

On Windows it rises an error:

foo = lambda (x,y): (y,x)
             ^
SyntaxError: invalid syntax

How to solve the problem?

Dmitry
  • 1,556
  • 1
  • 14
  • 26
  • Really? Works for me on a Win machine. – Jon Clements Jul 04 '12 at 11:39
  • Same Python version on both ? – bruno desthuilliers Jul 04 '12 at 11:40
  • 7
    "I found that a tuple parameter is deprecated from 3.0 version of Python" More precisely, it is tuple parameter "unpacking" that is removed. And it was not deprecated in 3.0 -- it was *removed* in 3.0. – newacct Jul 05 '12 at 01:00
  • 5
    The solution is wrong. It should be `lambda q:(q[0],q[1]) in states` (and that's how interjay described it). – jogojapan Mar 25 '13 at 02:25
  • 2
    If you are just doing what you show in your first code snippet, just use `def`. If you are applying the lambda to an iterable of tuples, `itertools`' `starmap` automatically unpacks for you, e.g., `starmap(lambda x, y: x + y, ((1, 2), (3, 4), (5, 6))) # => (3, 7, 11)` – tristanslater Oct 19 '21 at 19:21

1 Answers1

174

You are probably running Python 3.x on Windows, and Python 2.x on Linux. The ability to unpack tuple parameters was removed in Python 3: See PEP 3113.

You can manually unpack the tuple instead, which would work on both Python 2.x and 3.x:

foo = lambda xy: (xy[1],xy[0])

Or:

def foo(xy):
    x,y = xy
    return (y,x)
interjay
  • 107,303
  • 21
  • 270
  • 254
  • 6
    or `foo = lambda x, y: (y, x)` -> `foo(*(1,2))` (Works on Py3, I don't know for Py2...) – gecco Jul 04 '12 at 11:52
  • 33
    Thanks for this answer. Does anyone know of a beautiful functional-programming way to convert a tuple argument into two separate arguments, for readability's sake? – Joel Cross May 08 '17 at 00:10
  • 1
    Your code throws `TypeError: () takes 1 positional argument but 2 were given` error when I execute `lambda xy: (xy[0] + xy[1])` – Apurva Jun 15 '18 at 09:10
  • 1
    @Apurva I tested this and it works. You must be calling the lambda incorrectly. – interjay Jun 15 '18 at 10:48
  • 1
    It's worth noting that running your code through `2to3`, `modernize`, or `futurize` will catch the lambda and suggest almost this exact same change (except with `x_y` in place of `xy`). Whenever you're porting code from 2.x to 3.x and don't know both languages, it's worth running one of those tools (or an IDE's wrapper around them) at least for a sanity check and hints, if not to actually accept its output. – abarnert Sep 09 '18 at 20:24
  • 41
    This is so miserably ugly. I will always have a soft spot for Python, but this is just awful. – damd Feb 15 '20 at 22:26
  • 1
    I also think python needs to improve this. Super ugly – Bamdad Dashtban Mar 18 '21 at 11:58
  • 3
    @JoelCross "Does anyone know of a beautiful functional-programming way to convert a tuple argument into two separate arguments, for readability's sake?" Sorry for answering 5 years late... the function you're looking for is called curry! Curry takes a function of a pair and returns a function of 2 arguments. There's also curry3, which turns a function of a 3-tuple into a function of 3 arguments, etc. https://hoogle.haskell.org/?hoogle=curry In dynamically typed languages like python, we can usually define autoCurry, which turns a function of N-tuple to a function of N arguments for any N. – bagrounds Apr 23 '21 at 19:56
  • removed in python3, man that's sad. – WestCoastProjects May 03 '23 at 18:49