WilliamKF
WilliamKF

Reputation: 43129

Why do some Python functions have an extra set of parenthesis around the argument list?

I've seen some Python functions written like this:

def get_year((year,prefix,index,suffix)):
  return year

How does that differ (if at all) from other functions without the extra parentheses like this:

def do_format(yr,pfx,id,sfx):
  return "%s %s %s/%s"%(yr, id, pfx, sfx)

Or is it just a matter of taste in styles, or if they differ, can get_year() be rewritten to be in the style of do_format() or vice-versa without effecting existing caller's syntax?

Upvotes: 11

Views: 2519

Answers (3)

tdelaney
tdelaney

Reputation: 77337

These are all equivalent (the caller will not have to change):

# 2.x unpacks tuple as part of the function call, 3.x raises exception
def get_year((year,prefix,index,suffix)):
    """get year from (year, prefix, index, suffix) tuple"""
    return year

# 2.x and 3.x, you unpack tuple in the function call
def get_year(year_tuple):
    """get year from (year, prefix, index, suffix) tuple"""
    year, prefix, index, suffix = year_tuple
    return year

# 2.x and 3.x, speedier because you don't unpack what you don't need
def get_year(year_tuple):
    """get year from (year, prefix, index, suffix) tuple"""
    return year_tuple[0]

Upvotes: 1

John Y
John Y

Reputation: 14529

The get_year function in your example uses an automatically unpacked tuple parameter (this is the feature gone from Python 3). To call it, you give it a single parameter, and that parameter is expected to be a sequence containing four values.

# Invocation
my_input = [2013, 'a', 'b', 'c'] # sequence does NOT have to be a tuple!
my_year = get_year(my_input) # returns 2013

To rewrite this for Python 3 but not alter the invocation (in other words, to not break existing code which calls get_year):

def get_year(input_sequence):
    year, prefix, index, suffix = input_sequence
    return year

The above is essentially what tuple unpacking is doing for you automatically. In this particular case, you could simply write

def get_year(input_sequence):
    return input_sequence[0]

For further information, read PEP 3113.

Upvotes: 8

Rohit Jain
Rohit Jain

Reputation: 213223

The first function takes a single tuple argument, whereas the second function takes 4 arguments. You can pass those parameters individually, or as a tuple with splat operator, that will unpack the tuple into individual parameters.

E.g:

# Valid Invocations
print do_format(*('2001', '234', '12', '123'))  # Tuple Unpacking
print do_format('2001', '234', '12', '123')     # Separate Parameter
print get_year(('2001', '234', '12', '123'))

# Invalid invocation. 
print do_format(('2001', '234', '12', '123'))   # Passes tuple

Upvotes: 10

Related Questions