171

In the below example I would expect all the elements to be tuples, why is a tuple converted to a string when it only contains a single string?

>>> a = [('a'), ('b'), ('c', 'd')]
>>> a
['a', 'b', ('c', 'd')]
>>> 
>>> for elem in a:
...     print type(elem)
... 
<type 'str'>
<type 'str'>
<type 'tuple'>
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Russell
  • 2,692
  • 5
  • 23
  • 24
  • 2
    `('a')` just evaluates to `'a'` – obataku Oct 13 '12 at 19:24
  • 3
    Wow - 3 *correct* answers in 3 minutes :) However, note the secret of `,`: `a = 1, 2, 3; print a` –  Oct 13 '12 at 19:26
  • 38
    Brackets don't make a tuple, commas do. – cdarke Oct 13 '12 at 20:28
  • 19
    @cdarke, except for the empty tuple `()`, which only consists in a pair of parentheses. – Frédéric Hamidi Oct 14 '12 at 10:20
  • 2
    True, or rather, `False` - just about all an empty tuple is good for (if you see what I mean). – cdarke Oct 14 '12 at 13:12
  • Just to clarify the existing answers, parentheses are used for *grouping*, so `('a')` is taken as an expression that evaluates to `'a'`. Tuples need a comma to be a tuple, except the empty tuple, which is empty parentheses, `()`. – wjandrea Mar 26 '20 at 13:21
  • `tuple` is an object delimited by comma not an object enclosed in parentheses. So a singleton `tuple` would be like ('a',) or tuple('a') – aaronn May 29 '21 at 11:07
  • Should also be noted that `(True)` and `(False)` are boolean types so that evaluating `(1 == 2)` is equivalent to `1 == 2` – elPastor Nov 28 '22 at 17:30

5 Answers5

218

why is a tuple converted to a string when it only contains a single string?

a = [('a'), ('b'), ('c', 'd')]

Because those first two elements aren't tuples; they're just strings. The parenthesis don't automatically make them tuples. You have to add a comma after the string to indicate to python that it should be a tuple.

>>> type( ('a') )
<type 'str'>

>>> type( ('a',) )
<type 'tuple'>

To fix your example code, add commas here:

>>> a = [('a',), ('b',), ('c', 'd')]

             ^       ^

From the Python 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.

If you truly hate the trailing comma syntax, a workaround is to pass a list to the tuple() function:

x = tuple(['a'])
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
  • 11
    This isn't very elegant though and looks kind of confusing. Is there any other way? – Robert Moore Nov 26 '17 at 22:13
  • 3
    That doesn't seem to work. For example: tuple("abc") (with or without extra comma) gives ('a', 'b', 'c'), while ("abc",) gives ('abc'). So tuple() seems not to be a viable option here. – Ben Farmer May 02 '18 at 10:34
  • 4
    @Ben Have a look at the [docs](https://docs.python.org/2/library/functions.html#tuple). `tuple` accepts an *iterable*, which a string is (iterates over characters). If you insist on not using the trailing comma, then make an intermediate list: `tuple(['abc'])`. – Jonathon Reinhart May 02 '18 at 12:12
  • Sure, I am just saying that the tuple function doesn't negate the need for the comma. – Ben Farmer May 03 '18 at 07:21
  • Anything more explicit variant of it in python 3.x by any chance? – matanster May 03 '19 at 09:17
  • 1
    @matanster The language syntax has not changed in this regard. AFAIK the problem is the same for Python 2 and 3. – Jonathon Reinhart May 03 '19 at 10:39
26

Your first two examples are not tuples, they are strings. Single-item tuples require a trailing comma, as in:

>>> a = [('a',), ('b',), ('c', 'd')]
>>> a
[('a',), ('b',), ('c', 'd')]
Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
15

('a') is not a tuple, but just a string.

You need to add an extra comma at the end to make python take them as tuple: -

>>> a = [('a',), ('b',), ('c', 'd')]
>>> a
[('a',), ('b',), ('c', 'd')]
>>> 
Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
-1

=> If you need to convert list to tuple which have one id as a element. then this solution will help you.

x_list = [1]

x_tuple = tuple(x_list)

=> You will get this

(1,)

=> so now append 0 into list and then convert it into tuple

=> x_list.append(0)

=> x_tuple = tuple(x_list)

(1, 0)
kadamb
  • 1,532
  • 3
  • 29
  • 55
-2

Came across this page and I was surprised why no one mentioned one of the pretty common method for tuple with one element. May be this is version thing since this is a very old post. Anyway here it is:

>>> b = tuple(('a'))
>>> type(b)
<class 'tuple'>
Aaj Kaal
  • 1,205
  • 1
  • 9
  • 8
  • Strangely, this worked for me when the other answers didn't (passing a string value to a method, so i'm using a variable and not a raw string; maybe that's why `(foo,)` didn't work for me) – Jonathan E. Landrum Dec 07 '20 at 05:32
  • 1
    This won't work as intended if the input string has several characters. Try, for example, `tuple(('ab'))` and the result will be `('a', 'b')` instead of `('ab',)`. – Georgy Dec 10 '20 at 10:22
  • Generally preferable way in that case is to supply a list, so as to avoid trailing comma syntax. e.g. tuple(['ab']) – Aaj Kaal Dec 10 '20 at 12:49
  • 2
    This method only works for strings of length 1, nothing else. The correct syntax is `tuple([var])` – Peter Ye Mar 04 '21 at 22:45