2

I'm doing string formatting with tuples:

a = (1,2,3)
s = f"something in {a}"
print(s)
'something in (1, 2, 3)'

Everything is fine until I encounter a single-element tuple, which gives:

a = (1,)
s = f"something in {a}"
'something in (1,)'

what I actually want is:

'something in (1)'

How do I make tuple string formatting behaves consistently and remove the trailing comma?

Azuuu
  • 713
  • 5
  • 15
  • 1
    `type((1))` is `int`; `type((1,))` is `tuple`. Without trailing comma it's different type – JL0PD Jul 28 '21 at 03:41
  • @JL0PD Yeah, but how do I achieve the same formatting since I don't know what `a` will be like since it is served as a parameter in my own code. – Azuuu Jul 28 '21 at 03:43

4 Answers4

2

You could use your own formatting logic, e.g.

a = (1,2,3)
s = ','.join([str(x) for x in a])
print(s)  # 1,2,3

a = (1,)
s = ','.join([str(x) for x in a])
print(s)  # 1
Tim Biegeleisen
  • 451,927
  • 24
  • 239
  • 318
1

Python have 2 magic methods for formatting values: __str__ and __repr__.

__str__ may return any string, but __repr__ must return string that can be passed to eval and recreate value. It's not required, but you should do it. print tries to use __str__ if it's overriden, otherwise it uses __repr__. This means that you can use eval(repr(some_value)) to clone value, because most builtin types have overridden __repr__ properly. That's why you get trailing comma when formatting (1,).

If you really want to format tuple without trailing comma then use

def format_tuple(value):
    return "(" + ",".join(repr(v) for v in value) + ")"
# (1,) -> "(1)"
# () -> "()"
# (1, 2, 3,) -> "(1, 2, 3)"
# (1, 2, 3) -> "(1, 2, 3)"
JL0PD
  • 2,512
  • 1
  • 9
  • 18
1

You can use regex:

import re

tuple = (1,)
s = "something in "  + re.sub(r',(?=\))', '', str(tuple))
print(s)

Result:

something in (1)

You don't need any for loop etc.

Inputvector
  • 960
  • 8
  • 21
0

Based on @Tim Biegeleisen's answer:

a = (1,)
s = f"something in ({','.join([str(x) for x in a])})"
print(s)
'something in (1)'
Azuuu
  • 713
  • 5
  • 15
  • @Inputvector Great! But why `regular expression ` is superior to for-loop? – Azuuu Jul 28 '21 at 04:31
  • You can check here: https://stackoverflow.com/questions/42742810/speed-up-millions-of-regex-replacements-in-python-3/42747503#42747503 – Inputvector Jul 28 '21 at 04:42
  • 1
    @Inputvector Thanks! But in my case, performance isn't an issue for tuples are often less than 10 elements. I presume a for-loop combined with `f-string` might be more readable than a regular expression here. Thanks for showing me a great way of performance-boosting anyway! – Azuuu Jul 28 '21 at 05:40