What's New in Python 3.6: f-strings and More

A guide to the major new features introduced in Python 3.6, with a deep dive into the new formatted string literals (f-strings), which provide a more readable, concise, and faster way to format strings.

Python 3.6, released in late 2016, was a feature-packed release that brought several significant improvements to the language. While there were many valuable additions, one feature, in particular, has been so universally praised that it has changed the way almost all modern Python code is written: formatted string literals, or f-strings.

Let's explore this game-changing feature and some of the other notable additions in Python 3.6.

The Star of the Show: f-strings

For years, Python developers had two main ways to format strings: the older C-style % operator and the more modern str.format() method. Both work, but they can be verbose and hard to read.

f-strings provide a new, simpler, and more powerful way to embed expressions inside string literals.

The Old Way (str.format()):

name = "Alice"
age = 30

message = "My name is {} and I am {} years old.".format(name, age)

The New Way with f-strings:

name = "Alice"
age = 30

message = f"My name is {name} and I am {age} years old."

To create an f-string, you simply prefix the string literal with the letter f. You can then put any valid Python expression inside curly braces {} directly in the string. The expression is evaluated at runtime, and the result is inserted into the string.

This is not only more readable but also faster than the older methods.

Asynchronous Generators and Comprehensions

Python 3.5 introduced async and await. Python 3.6 builds on this by adding support for asynchronous generators and asynchronous comprehensions.

This allows for the creation of asynchronous data streams and the processing of asynchronous iterables in a concise way, further enhancing Python's capabilities for high-performance I/O-bound applications.

Underscores in Numeric Literals

A small but very welcome feature for readability. You can now use underscores in numeric literals to act as visual separators, making large numbers much easier to read.

# Instead of this:
large_number = 1000000000

# You can now write this:
large_number = 1_000_000_000

# This also works for hex and binary numbers
hex_value = 0x_FF_FF_FF

The underscores are ignored by the Python interpreter but make the code much more readable for humans.

New Dictionary Implementation

As an implementation detail, the dict type in CPython 3.6 was completely rewritten. A side effect of this new implementation was that dictionaries now consumed less memory and, more importantly, preserved their insertion order. This meant that when you iterated over a dictionary, it would yield items in the same order they were added.

While this was considered an implementation detail in 3.6, it was so popular and useful that it would be made an official part of the language specification in Python 3.7.

Secrets Module

A new secrets module was added to the standard library for generating cryptographically strong random numbers suitable for managing secrets like passwords, account authentication, and security tokens.

Conclusion

Python 3.6 was a fantastic release that significantly improved developer quality of life. f-strings have become the standard for string formatting, making Python code cleaner and more readable than ever before. The continued evolution of asyncio and the new, more efficient dictionary implementation further solidified Python's position as a modern, high-performance language.