Photo by Alex Chumak on Unsplash
Python is the third most commonly-used programming language. It has introduced many new features, simplifying and enhancing the development process. Yet, many developers remain unaware of the full potential that Python 3 has to offer.
This article will uncover ten lesser-known and underutilized capabilities in Python (v3.5 to v3.11). These hidden gems can improve your coding efficiency and productivity. So, without further ado, let’s dive into these fascinating Python 3 features.
1. Walrus Operator
It’s a new syntax introduced in Python 3.11 that assigns values to variables as part of a larger expression.
Old way
a = "This is a sample string text"
if len(a) > 10:
print("Length of string a = ", len(a))
New way
a = "This is a sample string text"
if (len_a := len(a)) > 10: # Note the walrus operator will compute value of len(a) and assign it to variable len_a
print("Length of string a = ", len_a)
2. Structural Pattern Matching
You might remember reading that Python doesn’t support switch statements because if-else can achieve the same result. You are in for a treat. Python3.10 introduced something similar.
Old way
def http_error(status):
if status == 400:
return "Bad request"
elif status == 404:
return "Not found"
elif status == 418:
return "I'm a teapot"
else:
return "Something's wrong with the internet"
New way
def http_error(status):
match status:
case 400:
return "Bad request"
case 404:
return "Not found"
case 418:
return "I'm a teapot"
case _: # This is a wildcard operator
return "Something's wrong with the internet"
3. Merging Dictionaries
Python3.9 introduced a new way of merging or updating dictionaries. It complements the existing dict.update and {**d1, **d2} methods of merging dictionaries.
Old way
x = {"key1": "value1 from x", "key2": "value2 from x"}
y = {"key2": "value2 from y", "key3": "value3 from y"}
print({ **x,** y})
print({ **y,** x}) # Note here keys of y would be given preference over keys of x
New way
x = {"key1": "value1 from x", "key2": "value2 from x"}
y = {"key2": "value2 from y", "key3": "value3 from y"}
# Note the usage of OR (|) operator
print(x | y)
prin(y | x) # Note here keys of y would be given preference over keys of x
4. Removing Prefix or Suffix
Python3.9 introduced dedicated methods to get rid of prefixes or suffixes in strings.
Old way
x = "prefixstring"
y = "stringsuffix"
print(x.split("prefix")[-1])
print(y.split("suffix")[0])
New way
x = "prefixstring"
y = "stringsuffix"
print(x.removeprefix("prefix"))
print(y.removesuffix("suffix"))
5. Positional Only Parameters
Python provides to define positional and keyword arguments for a function. But you can pass them interchangeably. Python3.8 introduced a way to enforce that you cannot pass positional arguments as keyword arguments.
Old way
def fun(pos_arg1, pos_arg2, key_arg_1 = None):
print("positional arguments: ", pos_arg1, pos_arg2)
print("Keyword arguments: ", key_arg_1)
# It will work
fun(1, 2, 3) # Passing keyword argument as positional argument
# It will also work
fun(pos_arg1=1, pos_arg2=2, key_arg_1=3) # Passing positional argument as keyword argument
New way
def fun(pos_arg1, pos_arg2, /, key_arg_1 = None):
print("positional arguments: ", pos_arg1, pos_arg2)
print("Keyword arguments: ", key_arg_1)
# It will work
fun(1, 2, 3) # Passing keyword argument as positional argument
# It won't work
fun(1, pos_arg2=2, key_arg_1=3) # Passing one positional argument as keyword argument
fun(pos_arg1=1, pos_arg2=2, key_arg_1=3) # Passing both positional arguments as keyword argument
6. Time with nanoseconds Precision
Did you ever need nanosecond precision in getting time to compare code performances? Python3.7 introduced new methods in the time library.
Old way
import time
start = time.time()
end = time.time()
print(end - start)
# Provides sub-second precision, though that precision varies by platform
# >> 2.7179718017578125e-05 Notice the precision is in e-05
New way
import time
start = time.time_ns()
end = time.time_ns()
print(end - start)
# Provides nanosecond precision
# >> 47000 Notice the figure is in nanoseconds
7. f-strings
Python3.6 introduced f-strings to provide an easy way of formatting strings.
Old way
a = 1
print("Value of a = {}".format(a))
New way
a = 1
print(f"Value of a = {a}")
8. Underscores in Numeric Literals
Python 3.6 introduced allowing adding underscores in numeric literals for better readability.
Old way
a = 1000000000000000 # try counting the number of 0's
print(type(a))
# >> <class 'int'>
New way
a = 1_000_000_000_000_000
print(type(a))
# >> <class 'int'>
9. Matrix Multiplication Operator
Python3.5 introduced a dedicated @ infix operator for matrix multiplication.
Old way
import numpy
x = numpy.ones(3)
m = numpy.eye(3)
print(x.dot(m))
New way
import numpy # NumPy 1.10 has support for the new operator:
x = numpy.ones(3)
m = numpy.eye(3)
print(x @ m) # @ is the new matrix matrix-multiplication operator
10. Approximate Equality
Python3.5 introduced dedicated methods to tell whether two values are approximately equal or “close” to each other.
Old way
a = 5.0
b = 4.99998
print(abs(a - b) <= 1e-5)
New way
import math
a = 5.0
b = 4.99998
print(math.isclose(a, b, rel_tol=1e-5))
Top comments (4)
Very useful but please use f-strings
Thanks for pointing that out. Made the "S" small case in
f-strings
this is useful
Wow this was so helpful! Some of these changes I knew of, but most of them I didn’t!!