4

What is the use of * in .format(*)? When using it in the format function below print(new_string.format(*sum_string)) it changes the value of sum_string in the output from 18 to 1 Why does that happen? I have read the following link about *args and **kwargs but couldn't understand how does that apply to the .format() function

What does ** (double star/asterisk) and * (star/asterisk) do for parameters?

sum_string = "18"
new_string = "This is a new string of value {}"

print(new_string.format(sum_string)) #it provides an output of value 18
print(new_string.format(*sum_string)) #it provides an output of value 1
NISARG DARU
  • 71
  • 1
  • 1
  • 4

1 Answers1

11

it has nothing to do with format. * unpacks the arguments so if there are, say 4 placeholders and 4 elements in your list, then format unpacks the args and fills the slots. Example:

args = range(4)
print(("{}_"*4).format(*args))

prints:

0_1_2_3_

In your second case:

print(new_string.format(*sum_string))

the arguments to unpack are the characters of the string (the string is seen as an iterable by the argument unpacking), and since there's only one placeholder, only the first character is formatted & printed (and as opposed to warnings you could get with C compilers and printf, python doesn't warn you about your list of arguments being too long, it just doesn't use all of them)

With several placeholders you'd witness this:

>>> args = "abcd"
>>> print("{}_{}_{}_{}").format(*args))
a_b_c_d
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • 2
    Yep, just for illustration purposes of what you described: `new_string = "This is a new string of value {}{}"` and `new_string.format(*sum_string)` will "work" as then 2 placeholders are present. – Cleb Sep 24 '18 at 08:39
  • 1
    You are right about the unpacking, but `"{}_"*4` has nothing to do with unpacking. It is just string multiplication, so a form of concatenation. `"{}_"*4` is the same as `"{}_" + "{}_" + "{}_" + "{}_"` which is the same as `"{}_{}_{}_{}_"` which is only then handled by `.format` to fill in the slots. What's more, this kind of multiplication can be applied to all objects that can also be concatenated. So `(1,) * 3` will yield `(1, 1, 1)`. A catch to remember is that this kind of concatenation also duplicates the pointers, so you have to be careful with concatenating mutable objects (eg lists). – Hielke Walinga Sep 24 '18 at 08:55
  • 1
    I could change that, it was just to generate a formatting string quickly – Jean-François Fabre Sep 24 '18 at 09:02
  • Thank you, I was confused about tuple; I thought `(20, 100, 1.0)` might require three different place holders, but now I understand that without specifying the `*` the entire tuple is substituted to only one place holder and to substitute to three distinct place holders, it needs to be unpacked using the `*` or `*args` – NISARG DARU Sep 24 '18 at 10:34