String formatting in Python
The previous answers have used % formatting, which is being phased out in Python 3.0+. Assuming you're using Python 2.6+, a more future-proof formatting system is described here:
http://docs.python.org/library/string.html#formatstrings
Although there are more advanced features as well, the simplest form ends up looking very close to what you wrote:
>>> "[{0}, {1}, {2}]".format(1, 2, 3)
[1, 2, 3]
String formatting in Python 3
Here are the docs about the "new" format syntax. An example would be:
"({:d} goals, ${:d})".format(self.goals, self.penalties)
If both goals
and penalties
are integers (i.e. their default format is ok), it could be shortened to:
"({} goals, ${})".format(self.goals, self.penalties)
And since the parameters are fields of self
, there's also a way of doing it using a single argument twice (as @Burhan Khalid noted in the comments):
"({0.goals} goals, ${0.penalties})".format(self)
Explaining:
{}
means just the next positional argument, with default format;{0}
means the argument with index0
, with default format;{:d}
is the next positional argument, with decimal integer format;{0:d}
is the argument with index0
, with decimal integer format.
There are many others things you can do when selecting an argument (using named arguments instead of positional ones, accessing fields, etc) and many format options as well (padding the number, using thousands separators, showing sign or not, etc). Some other examples:
"({goals} goals, ${penalties})".format(goals=2, penalties=4)
"({goals} goals, ${penalties})".format(**self.__dict__)
"first goal: {0.goal_list[0]}".format(self)
"second goal: {.goal_list[1]}".format(self)
"conversion rate: {:.2f}".format(self.goals / self.shots) # '0.20'
"conversion rate: {:.2%}".format(self.goals / self.shots) # '20.45%'
"conversion rate: {:.0%}".format(self.goals / self.shots) # '20%'
"self: {!s}".format(self) # 'Player: Bob'
"self: {!r}".format(self) # '<__main__.Player instance at 0x00BF7260>'
"games: {:>3}".format(player1.games) # 'games: 123'
"games: {:>3}".format(player2.games) # 'games: 4'
"games: {:0>3}".format(player2.games) # 'games: 004'
Note: As others pointed out, the new format does not supersede the former, both are available both in Python 3 and the newer versions of Python 2 as well. Some may say it's a matter of preference, but IMHO the newer is much more expressive than the older, and should be used whenever writing new code (unless it's targeting older environments, of course).
String formatting in python 3 without print function
this "%s"
format has been borrowed from C printf
format, but is much more interesting because it doesn't belong to print
statement. Note that it involves just one argument passed to print
(or to any function BTW):
print("%s%s" % (a,a))
and not (like C) a variable number of arguments passed to some functions that accept & understand them:
printf("%s%s,a,a);
It's a standalone way of creating a string from a string template & its arguments (which for instance solves the tedious issue of: "I want a logger with formatting capabilities" which can be achieved with great effort in C or C++, using variable arguments + vsprintf
or C++11 variadic recursive templates).
Note that this format style is now considered legacy. Now you'd better use format
, where the placeholders are wrapped in {}
.
One of the direct advantages here is that since the argument is repeated you just have to do:
int("{0}{0}".format(a))
(it references twice the sole argument in position 0)
Both legacy and format
syntaxes are detailed with examples on https://pyformat.info/
or since python 3.6 you can use fstrings:
>>> a = 12
>>> int(f"{a}{a}")
1212
How to set the spaces in a string format in Python 3
Using str.format
>>> length = 20
>>> string = "some string"
>>> print('{1:>{0}}'.format(length, string))
some string
String formatting: % vs. .format vs. f-string literal
To answer your first question... .format
just seems more sophisticated in many ways. An annoying thing about %
is also how it can either take a variable or a tuple. You'd think the following would always work:
"Hello %s" % name
yet, if name
happens to be (1, 2, 3)
, it will throw a TypeError
. To guarantee that it always prints, you'd need to do
"Hello %s" % (name,) # supply the single argument as a single-item tuple
which is just ugly. .format
doesn't have those issues. Also in the second example you gave, the .format
example is much cleaner looking.
Only use it for backwards compatibility with Python 2.5.
To answer your second question, string formatting happens at the same time as any other operation - when the string formatting expression is evaluated. And Python, not being a lazy language, evaluates expressions before calling functions, so the expression log.debug("some debug info: %s" % some_info)
will first evaluate the string to, e.g. "some debug info: roflcopters are active"
, then that string will be passed to log.debug()
.
Python 3 Nesting String format
Your "nested" format string needs to be formatted twice. Any curly braces you want to keep for the second time needs to be escaped in the first, thus {
becomes {{
and }
becomes }}
. Also, since you can't use the f
prefix twice, You can explicitly call format
for the second formatting.
What you're looking for is this:
for i in range(1, size + 1):
line = f"{i}" * i
print(f"{{0:>{size}}}".format(line))
So first string formatting turns f"{{0:>{size}}}"
into {0:>3}
, thus when reaching the explicit calling of format
you basically get print("{0:>3}".format(line))
.
python 3 string formatting (alignment)
You could try:
"{:>10d}".format(n)
where n is an int to pad-left numbers and
"{:>10s}".format(s)
, where s is a string to pad-left strings
Edit: choosing 10 is arbitrary.. I would suggest first determining the max length.
But I'm not sure this is what you want..
Anyways, this link contains some info on string formatting:
String formatting
You can try this:
def align(word, number):
return "{:<10s}{:>10d}".format(word, number)
This will pad-right your string with 10 spaces and pad-left your number with 10 spaces, giving the desired result
Example:
align('Hello', 3454)
align('nice', 222)
align('bye', 45433)
align('well', 3424)
Related Topics
How to Sort Unicode Strings Alphabetically in Python
Differencebetween Slice Assignment That Slices the Whole List and Direct Assignment
How to Get Indices of a Sorted Array in Python
How to Check a String for Specific Characters
How to Save a Trained Model in Pytorch
Loop That Also Accesses Previous and Next Values
Weird Try-Except-Else-Finally Behavior with Return Statements
Python Cannot Handle Numbers String Starting with 0. Why
How to Limit Concurrency with Python Asyncio
Python Numpy Valueerror: Operands Could Not Be Broadcast Together with Shapes
How to Flatten a Nested JSON Recursively, with Flatten_JSON
Django Passing Custom Form Parameters to Formset
How to Set Environment Variables in Pycharm
How to Debug in Django, the Good Way
Python Process Pool Non-Daemonic