I would like to translate the following code
print "%-*s" % (10, 'foo')
which would print foo with 7 trailing spaces (field width == 10, left justified), into a Python 3 .format() call, but not having much luck googling.. Is it possible?
'{1:{0}}'.format(10, 'foo')
or with implicit indices:
'{:{}}'.format('foo', 10)
See https://docs.python.org/2/library/string.html#format-string-syntax
This should work.
'{:<10}'.format('foo')
How about this:
"{:<10}".format("foo")
Which will produce (spaces replaced by underscores):
'foo_______'
For more information check out the section Format specification mini-language of the python documentation.
Related
I'm new to python, and I just want to know the difference between those examples.
Does it differ when it comes to the execution speed?
When do I use one of them instead of the other?
x: int = 64
print(f"Your Number is {x}")
and
x: int = 64
txt = "Your Number is {}"
print(txt.format(x))
Thank you in advance!
There is no difference, technically speaking. The f-string format is recommended because it is more recent: it was introduced in Python 3.6. RealPython explains that f-strings are faster than str.format().
With f-strings the syntax is less verbose. Suppose you have the following variables:
first_name = "Eric"
last_name = "Idle"
age = 74
profession = "comedian"
affiliation = "Monty Python"
This is how you would format a str.format() statement.
print(("Hello, {name} {surname}. You are {age}. " +
"You are a {profession}. You were a member of {affiliation}.") \
.format(name=first_name, surname=last_name, age=age,\
profession=profession, affiliation=affiliation))
With formatting strings, it is considerably shortened:
print(f"Hello {first_name} {last_name}. You are {age}" +
f"You are a {profession}. You were a member of {affiliation}.")
Not only that: formatting strings offer a lot of nifty tricks, because they are evaluated at runtime:
>>> name="elvis" # note it is lowercase
>>> print(f"WOW THAT IS {name.upper()}")
'WOW THAT IS ELVIS'
This can be done inside a str.format(...) statement too, but f-strings make it cleaner and less cumbersome. Plus, you can also specify formatting inside the curly braces:
>>> value=123
>>> print(f"{value=}")
'value = 123'
Which normally you should have written as print("value = {number}".format(number=value)). Also, you can evaluate expressions:
>>> print(f"{value % 2 =}")
'value % 2 = 1`
And also format numbers:
>>> other_value = 123.456
>>> print(f"{other_value:.2f}") # will just print up to the second digit
'123.45'
And dates:
>>> from datetime.datetime import now
>>> print(f"{now=:%Y-%m-%d}")
'now=2022-02-02'
Python f-strings were added in 3.6. Therefore you should consider using format() if you need compatibility with earlier versions. Otherwise, use f-strings.
On macOS 12.1 running 3 GHz 10-Core Intel Xeon W and Python 3.10.2, f-strings are significantly faster (~60%)
Well, personally I use f string all the time, except when I'm dealing with floats or things like that, that require a specific formatting, that's when using .format is more suitable.
But if you are not dealing with text that require a specific formatting you should use f string, its easier to read.
This:
print '{:x<4d}'.format(34)
prints this:
34xx
How can I do this:
width = 13
print '{:x<|width|d}'.format(34)
to get this:
34xxxxxxxxxxx
You can put one format field inside of the other:
>>> width = 13
>>> print '{:x<{}d}'.format(34, width)
34xxxxxxxxxxx
>>>
From the docs:
A format_spec field can also include nested replacement fields within
it. These nested replacement fields can contain only a field name;
conversion flags and format specifications are not allowed. The
replacement fields within the format_spec are substituted before the
format_spec string is interpreted. This allows the formatting of a
value to be dynamically specified.
Note however that the nesting can only go one level deep.
This works
('{:x<%dd}' % width).format(34)
this will work:
>>> width = 13
>>> print '{:x<{}d}'.format(34,width)
34xxxxxxxxxxx
You can nest arguments in format, using kwargs allows you to be more explicit and less susceptible to confusing results:
fillchar = 'x'
width = 13
print "{:{f}<{w}d}".format(34, w=width, f=fillchar)
I'm making a socket client and need to define a function which sends the following kind of message to server: sometext,[name_1],[name_2],...,[name_n]. Actually the message is more complex, but for the sake of an example I simplified it.
Where:
... - represents the rest of the names (comma delimited) between name_2 and the last name_n
there could be arbitrary number of names each time
I know there are *args and **kwargs, but how to correctly use them in this case with str.format()? I need something like this:
def send_names(*args):
print('sometext,{*args},'.format(*args)) # as an example we just print
I know this code doesn't work because {*args} is illegal here.
The code works when I know the number of *args beforehand, like in here:
def send_names(*args):
print('sometext,{0},{1},{2}'.format(*args)) # as an example we just print
What am I missing?
You can join the *args to accomplish what you want:
def send_names(*args):
print('sometext, {0}'.format(', '.join(args)))
send_names('message1', 'message2', 'message3')
result:
sometext, message1, message2, message3
You cannot use *args or **kwargs to apply to a variable number of slots, no. You'd have to create the slots yourself based on the length:
','.join(['{}'] * len(args)).format(*args)
You can then interpolate the result of that into another template as needed. The above works with any type of argument normally accepted by a formatting slot.
Demo:
>>> args = ('foo', 'bar')
>>> ','.join(['{}'] * len(args)).format(*args)
'foo,bar'
>>> args = ('foo', 'bar', 'baz')
>>> ','.join(['{}'] * len(args)).format(*args)
'foo,bar,baz'
>>> args = (1, 2, 3)
>>> ','.join(['{}'] * len(args)).format(*args)
'1,2,3'
I think you should avoid using .format and just ', '.join the args as needed. You didn't mention any specific reason why you need to .format the strings in the question. Just like the solution by #Selcuk
I am trying to write a function which takes two arguments:
an object
a formatter string (as specified in docs)
which then returns a formatted string:
What I tried is sort of:
def my_formatter(x, form):
return str(x).format(form)
What I am expecting is:
s = my_formatter(5, "%2f")
# s = 05
t = my_formatter(5, "%.2")
# t = 5.00
etc...
The format function unfortunately does not work like that. Any ideas?
For that style of formatting you'd have to use the string % values string formatting operation:
def my_formatter(x, form):
return form % x
You'd also have to alter your format; to get 05 you'd have to use "%02d", not "%2f".
You were getting confused by the str.format() method, which uses a different formatting syntax, and you got the arguments swapped; you'd use form.format(x) instead.
You probably want to look into the built-in format() function here; the syntax is slightly different, but offers more features:
>>> format(5, '02d')
'05'
>>> format(5, '.2f')
'5.00'
That's pretty close to what you were already using, minus the %.
When I run the following code in Python 2.5.2:
for x in range(1, 11):
print '{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x)
I get:
Traceback (most recent call last):
File "<pyshell#9>", line 2, in <module>
print '{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x)
AttributeError: 'str' object has no attribute 'format'
I don't understand the problem.
From dir('hello') there is no format attribute.
How can I solve this?
The str.format method was introduced in Python 3.0, and backported to Python 2.6 and later.
Your example code seems to be written for Python 2.6 or later, where the str.format method was introduced.
For Python versions below 2.6, use the % operator to interpolate a sequence of values into a format string:
for x in range(1, 11):
print '%2d %3d %4d' % (x, x*x, x*x*x)
You should also be aware that this operator can interpolate by name from a mapping, instead of just positional arguments:
>>> "%(foo)s %(bar)d" % {'bar': 42, 'foo': "spam", 'baz': None}
'spam 42'
In combination with the fact that the built-in vars() function returns attributes of a namespace as a mapping, this can be very handy:
>>> bar = 42
>>> foo = "spam"
>>> baz = None
>>> "%(foo)s %(bar)d" % vars()
'spam 42'
I believe that is a Python 3.0 feature, although it is in version 2.6. But if you have a version of Python below that, that type of string formatting will not work.
If you are trying to print formatted strings in general, use Python's printf-style syntax through the % operator. For example:
print '%.2f' % some_var
Which Python version do you use?
Edit
For Python 2.5, use "x = %s" % (x) (for printing strings)
If you want to print other types, see here.
Although the existing answers describe the causes and point in the direction of a fix, none of them actually provide a solution that accomplishes what the question asks.
You have two options to solve the problem. The first is to upgrade to Python 2.6 or greater, which supports the format string construct.
The second option is to use the older string formatting with the % operator. The equivalent code of what you've presented would be as follows.
for x in range(1,11):
print '%2d %3d %4d' % (x, x*x, x*x*x)
This code snipped produces exactly the same output in Python 2.5 as your example code produces in Python 2.6 and greater.
Use this:
print "test some char {} and also number {}".format('a', 123)
result:
test some char a and also number 123