20

Just came across this little bit of weirdness in Python and thought I'd document it write it as a question here in case anyone else is trying to find an answer with the same fruitless search terms I was

Looks like tuple unpacking makes it so you can't return a tuple of length 1 if you're expecting to iterate over the return value. Although it seems that looks are deceiving. See the answers.

>>> def returns_list_of_one(a):
...     return [a]
...
>>> def returns_tuple_of_one(a):
...     return (a)
...
>>> def returns_tuple_of_two(a):
...     return (a, a)
...
>>> for n in returns_list_of_one(10):
...    print n
...
10
>>> for n in returns_tuple_of_two(10):
...     print n
...
10
10
>>> for n in returns_tuple_of_one(10):
...     print n
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>>
mcstrother
  • 6,867
  • 5
  • 22
  • 18
  • 1
    Thanks to everyone for the explanation. That makes perfect sense. Can anyone explain the vote-down? You can see how my initial thought that it had to do with returning the value from the function rather than the actual construction of the tuple itself lead me to do a bunch of fruitless searching and experimenting, so it seemed appropriate to bring up. (Though clearly my choice of words could have been better, see edit above.) – mcstrother Jul 13 '11 at 19:51

4 Answers4

33

You need to explicitly make it a tuple (see the official tutorial):

def returns_tuple_of_one(a):
    return (a, )
multipleinterfaces
  • 8,913
  • 4
  • 30
  • 34
14

This is not a bug, a one-tuple is constructed by val, or (val,). It is the comma and not the parentheses that define the tuple in python syntax.

Your function is actually returning a itself, which is of course not iterable.

To quote sequence and tuple docs:

A special problem is the construction of tuples containing 0 or 1 items: the syntax has some extra quirks to accommodate these. Empty tuples are constructed by an empty pair of parentheses; a tuple with one item is constructed by following a value with a comma (it is not sufficient to enclose a single value in parentheses). Ugly, but effective.

shelhamer
  • 29,752
  • 2
  • 30
  • 33
2

(a) is not a single element tuple, it's just a parenthesized expression. Use (a,).

hammar
  • 138,522
  • 17
  • 304
  • 385
-2

Instead of that ugly comma, you can use the tuple() built-in method.

def returns_tuple_of_one(a):
    return tuple(a)
Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
John
  • 5
  • 1
  • 4
    I agree that's prettier, but unfortunately `tuple(10)` gives the same `TypeError: 'int' object is not iterable`. – mcstrother Mar 28 '14 at 01:26
  • 3
    Also unfortunately, `tuple('HELLO')` yields `('H', 'E', 'L', 'L', 'O')`, which I would not expect from `returns_tuple_of_one('HELLO')`. – ethanbustad Dec 31 '14 at 00:39