String Formatting for Python Syntax Analysis

  • 2021-06-28 13:02:56
  • OfStack

Preorder

There should be one - and preferably only one - obvious way to do it.
- the Zen of Python
Python advocates one, and it's best to have only one way to do one thing

Although Python has been advocated above, it does not do this in string formatting.

String Formatting

Knock on the blackboard and highlight: There are at least three common ways to format strings in Python:

%-formatting format (pre-Python2.6, recommended for output) str.format() format (Python2.6, recommended for string splicing) f-string format (Python3.6, recommended)

1. printf-style string formatting (%-formatting format)

This was the only way before Python2.6, using the same syntax as printf function 1 in C.

Basic syntax: format% value (where format is a string), the% conversion marker in format will be replaced with zero or more value entries

Basic usage


# coding in Python3.7
print('this is %s blog written in %d%%%02d%%%d %02d:%d:%06.2f' 
  % ('TinyDolphin', 2019, 5, 31, 9, 30, 22.3333))
# this is TinyDolphin blog written in 2019%05%31 09:30:022.33

print('title=%(title)s, author=%(name)s' 
  % {'name': 'TinyDolphin', 'title': 'Python  Grammar Analysis: String Formatting '})
# title=Python  Grammar Analysis: String Formatting , author=TinyDolphin

print('%0*.*f' % (6, 2, 2.345))
# 002.35

printf Syntax

For this formatting operation, the following are important points of knowledge:

1. For these conversion marker characters, the following order must be followed:

% -- > (name) -- > '#','-','0','+', ''-- > m.n | m -- > d, s, r, f

2. Common conversion types:

%s formatted string (str() function) %r formatted string (repr() function) %d Formatted Integer %f formats floating-point numbers to specify the precision after the decimal point

3. Common conversion marker characters:

-For left alignment +Display a plus sign (+) before positive numbers #Displays zero ('0') in front of octal numbers and'0x'or'0X' in front of 106 (depending on whether'x'or'X' is used) 0 Displays a number preceded by'0', not the default space %'%%'outputs a single 1'%' m.n indicates that m is the minimum total width of the display and n is the number of digits after the decimal point *Define width or decimal precision (used when m.n values cannot be pre-specified) (var) Mapping variable (dictionary parameter)

2. The way the string is formatted (str.format())

Starting with Python2.6, a new function str.format() was added to format strings, which enhanced string formatting capabilities, such as support for location mapping, keyword mapping, object attribute mapping, subscript mapping, and so on.

The basic syntax is to replace the previous one with {} and:, for example:'%03.2f'was rewritten to'{:03.2f}'.

Two formatting methods:

str.format(*args, **kwargs)
Formatting operations for strings.
str contains substitution fields enclosed by the string literal value AND {}.
Each replacement field: index of location parameter The name of the OR keyword parameter

str.format_map(mapping)
Similar to str.foramt (**mapping)
The difference: mapping is used directly instead of being copied to an dict.

PS:Python has a built-in function format (value, format_spec: Converts to type (value). format (value, format_spec)

Basic usage

1. Access parameters by location


'{0}-{1}-{2}'.format('a', 'b', 'c')   # 'a-b-c'
'{}-{}-{}'.format('a', 'b', 'c')    # 'a-b-c'
'{2}-{1}-{0}'.format('a', 'b', 'c')   # 'c-b-a'
'{2}-{1}-{0}'.format(*'abc')      # 'c-b-a'

args = ['a', 'b', 'c']
'{2}-{1}-{0}'.format(*args)       # 'c-b-a'

'{0}-{1}-{0}'.format(*['abc', 'def'])  # 'abc-def-abc'

2. Access parameters by name


'{a}-{b}'.format(a='1', b='2')     # '1-2'

kwargs = {'a':'1', 'b':'2'}
'{a}-{b}'.format(**kwargs)       # '1-2'

3. Accessing the properties of parameters


class Point:
  def __init__(self, x, y):
    self.x, self.y = x, y
  def __str__(self):
    return 'Point({self.x}, {self.y})'.format(self=self)
    
str(Point(3, 4))            # 'Point(3, 4)'

4. Items to access parameters


point = (3, 5)
'X:{0[0]} Y:{0[1]}'.format(point)    # 'X:3 Y:5'

5. Replace%s and%r(!s,!r)


'str() = {!s}; repr() = {!r}'.format('a', 'a') # "str() = a; repr() = 'a'"

6. Align text and set width (: < ,: ^,: > )


'{:<20}'.format('left aligned')     # 'left aligned    '
'{:>20}'.format('right aligned')    # '    right aligned'
'{:^20}'.format('centered')       # '   centered   '
#  Use  '*'  As fill character 
'{:*^20}'.format('centered')      # '******centered******'

7. Substitute%+f,%-f and%f and specify plus or minus sign (:+,:-,:)


'{:+f} {:+f}'.format(3.14, -3.14)    # '+3.140000 -3.140000'
'{: f} {: f}'.format(3.14, -3.14)    # ' 3.140000 -3.140000'  Plus sign- > Spaces 
'{:-f} {:-f}'.format(3.14, -3.14)    # '3.140000 -3.140000' == '{:f} {:f}'

8. Replace%x and%o and convert values based on different scales (: x,: d,: o,: b)


'int:{0:d} hex:{0:x} oct:{0:o} bin:{0:b}'.format(42)
# 'int:42 hex:2a oct:52 bin:101010'
'int:{0:d} hex:{0:#x} oct:{0:#o} bin:{0:#b}'.format(42)
# 'int:42 hex:0x2a oct:0o52 bin:0b101010'
# '#' :  Prefix: 0x , 0o , 0b

9. Use commas as thousands separators (:,)


'{:,}'.format(123456789)        # '123,456,789'

10. Expressed as a percentage (:.2%)


'{0}-{1}-{2}'.format('a', 'b', 'c')   # 'a-b-c'
'{}-{}-{}'.format('a', 'b', 'c')    # 'a-b-c'
'{2}-{1}-{0}'.format('a', 'b', 'c')   # 'c-b-a'
'{2}-{1}-{0}'.format(*'abc')      # 'c-b-a'

args = ['a', 'b', 'c']
'{2}-{1}-{0}'.format(*args)       # 'c-b-a'

'{0}-{1}-{0}'.format(*['abc', 'def'])  # 'abc-def-abc'
0

11. Use specific types of proprietary formatting


'{0}-{1}-{2}'.format('a', 'b', 'c')   # 'a-b-c'
'{}-{}-{}'.format('a', 'b', 'c')    # 'a-b-c'
'{2}-{1}-{0}'.format('a', 'b', 'c')   # 'c-b-a'
'{2}-{1}-{0}'.format(*'abc')      # 'c-b-a'

args = ['a', 'b', 'c']
'{2}-{1}-{0}'.format(*args)       # 'c-b-a'

'{0}-{1}-{0}'.format(*['abc', 'def'])  # 'abc-def-abc'
1

12. Nested parameters and more complex examples

slightly

3. Format string literal value (f-string format)

Is a string literal value prefixed with'f'or'F'.

Parts other than curly brackets are treated as their literal value, with the exception of double curly brackets'{or'}}'replaced by the corresponding single curly bracket.

The syntax is as follows:

Single curly bracket'{', indicating a replacement field (beginning with the Python expression)
+There may be an exclamation mark'!'Conversion Characters for Indicators
+There may be a format specifier marked with a colon':'
+end with a right curly brace'}'

Note: Expressions in literal values of formatted strings:

Handle as a normal Python expression (this is important and powerful) Empty expressions are not allowed lambda expression must be explicitly parenthesized Can contain line breaks (for example, in a 3-quote string) Cannot contain comments Evaluated from left to right

If a converter is specified, the result of the expression evaluation is converted and then formatted.Formatted using the Python built-in function format().

Basic Usage


'{0}-{1}-{2}'.format('a', 'b', 'c')   # 'a-b-c'
'{}-{}-{}'.format('a', 'b', 'c')    # 'a-b-c'
'{2}-{1}-{0}'.format('a', 'b', 'c')   # 'c-b-a'
'{2}-{1}-{0}'.format(*'abc')      # 'c-b-a'

args = ['a', 'b', 'c']
'{2}-{1}-{0}'.format(*args)       # 'c-b-a'

'{0}-{1}-{0}'.format(*['abc', 'def'])  # 'abc-def-abc'
2

PS: A little different from str.format (): In str.format (), non-numeric indexes are automatically converted to strings, whereas f-strings does not.


kwargs = {'a':1, 'b':2}
#  Use  str.format()
'a={kwargs[a]}'.format(kwargs=kwargs)  # 'a=1'

#  Use  f-string
f"a={kwargs[a]}"            #  ×   exception occurred 
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined

#  Use correctly  f-string
f"a={kwargs['a']}"           # 'a=1'

summary

Compare from the following three aspects:

Speed: f-string > %-formatting > str.format()
Functionally: f-string > str.format() > %-formatting
Readability: f-string > str.format() > %-formatting

For speed verification, the author does not verify it here.

Recommended scenarios:

%-formatting:Python2, due to its performance advantages, is preferred for some operations involving output
str.format():Python2, due to its functional advantages, is preferred for some operations involving string splicing.
f-string:Python3, strongly recommended


Related articles: