Back to Blog
Python

Using the Python format Function for String Formatting

Learn how the python format function works, including placeholders, format specifiers, alignment, and number formatting, with practical examples and comparisons to f-s...

pythonstring formattingformat specifiersf-stringsformat method
Illustration of a Python string with curly braces and a formatted value, representing the format function.

The python format function is a built-in method on strings that lets you insert values into placeholders and control their appearance. It is a flexible alternative to older %-style formatting and remains useful when the format string itself must be dynamic. This article explains the syntax, the format specification mini-language, and the practical decisions around when to use format() versus f-strings.

How the format Function Works

The format() method is called on a string containing replacement fields, each enclosed in curly braces {}. The values passed as arguments are substituted into those fields in order. You can also use positional indices or keyword names to map values explicitly.

name = "Ada" age = 36 print("{} is {} years old".format(name, age)) print("{0} is {1} years old".format(name, age)) print("{name} is {age} years old".format(name=name, age=age))

All three produce the same output. The first relies on implicit order, the second uses explicit positional indices, and the third uses keyword arguments. Mixing positional and keyword arguments in the same format string is allowed but can reduce readability, so it is usually better to choose one style.

Format Specifiers and the Mini-Language

Each replacement field can include a format specifier after a colon. The specifier controls alignment, width, numeric precision, and type conversion. The general syntax is {argument:format_specifier}.

value = 42 print("{:>10}".format(value)) # right-aligned in width 10 print("{:<10}".format(value)) # left-aligned print("{:^10}".format(value)) # centered print("{:010}".format(value)) # zero-padded to width 10

The alignment characters are > for right, < for left, and ^ for center. A fill character can be placed before the alignment character, as in {:*^10} to center with asterisks. The width is an integer that sets the minimum field width; the value is padded if shorter.

Formatting Numbers and Floats

Numeric types have their own set of format codes. For integers, d is the default, but you can use x for hexadecimal, o for octal, or b for binary. For floats, f uses fixed-point notation, e uses scientific notation, and g chooses the shorter representation.

pi = 3.14159265 print("{:.2f}".format(pi)) # 3.14 print("{:e}".format(pi)) # 3.141593e+00 print("{:+.2f}".format(pi)) # +3.14 print("{:,.2f}".format(1234567.891)) # 1,234,567.89

The precision after the dot specifies the number of digits after the decimal point for f and e, or the total number of significant digits for g. The comma adds thousands separators, which is useful for large numbers in reports or logs.

Accessing Object Attributes and Dictionary Keys

Format fields can reference attributes or dictionary keys using the dot and bracket syntax. This is especially handy when formatting objects or mapping data without manually extracting each value.

class User: def __init__(self, name, role): self.name = name self.role = role user = User("Alice", "admin") print("{0.name} has role {0.role}".format(user)) data = {"name": "Bob", "score": 95} print("{name} scored {score}".format(**data))

For dictionary access, the ** operator unpacks the mapping into keyword arguments. Attribute access works on any object that exposes the named attribute. This keeps the format string concise and avoids manual concatenation.

Comparing format() with f-strings

Since Python 3.6, f-strings provide a more concise way to embed expressions directly in string literals. For most static strings, f-strings are preferred because they are more readable and execute faster. The format() method still matters when the format template is built at runtime, such as when it comes from configuration or user input.

name = "Carol" # f-string print(f"Hello {name}") # format() print("Hello {}".format(name))

F-strings evaluate expressions at runtime, so they cannot be stored and reused with different values. If you need to apply the same template to many records, format() is the appropriate tool. For example, a reporting tool might read a format pattern from a config file and apply it to each data row.

Common Pitfalls and Edge Cases

One frequent mistake is forgetting to escape literal braces. To include a brace in the output, double it: {{ and }}. Another issue is passing the wrong number of arguments, which raises an IndexError or KeyError depending on the field type.

print("{{}}".format()) # outputs {} # print("{}".format()) # IndexError: Replacement index 0 out of range

Format specifiers are strict: an invalid code raises ValueError. For example, "{:q}".format(5) fails because q is not a valid type. Always validate format strings that come from external sources, as a malformed specifier will crash the program.

Performance and Maintainability Considerations

F-strings are generally faster than format() because they are parsed at compile time, while format() parses the format string at runtime. In tight loops that build many strings, this difference can matter. However, the performance gap is rarely significant for typical application code. The larger maintainability concern is that format() separates the template from the values, which can make long strings harder to read. F-strings keep the expression next to the placeholder, improving readability for static templates.

When you need a dynamic template, format() is the only standard option. In that case, document the expected format specifiers and validate them before use. Also consider using named fields to make the template self-explanatory, especially when the same value appears multiple times.

template = "{name} (id: {id:05d})" for record in records: print(template.format(**record))

This pattern keeps the formatting logic centralized and avoids duplicating the same specifier across many lines. If the format needs to change, you update one template instead of every call site.

python format function: Practical Usage and Code Examples | RYUSLOG DEV