I subscribed to the Real Python mailing list two years ago, and I learned a lot of tips and tricks during that time. Even though it might seem like an odd way to learn Python, I have found it to be extremely helpful. I have written down some notes about the most useful tips and tricks that I have learned over the last two years, and I wanted to share them with you today.
1. Merging two dictionaries.
Question: How to merge two dictionaries?
Answer: Using The unpack **
operator.
>>> x = {'a': 10, 'b': 8}
>>> x = {'a': 1, 'b': 2}
>>> y = {'b': 3, 'c': 4}
>>> z = {**x, **y}
>>> z
{'a': 1, 'b': 3, 'c': 4}
2. A way to test multiple conditions at once.
Question: How to test multiple flags at once?
Answer: Using any
, in
, all
operators instead of or
or and
.
>>> x, y, z = 0, 1, 0
>>> if x == 1 or y == 1 or z == 1:
... print("Passed")
...
Passed
>>> if 1 in (x, y, z):
... print("Passed")
...
Passed
>>> if any((x, y, z)):
... print("Passed")
...
Passed
>>> x, y, z = 1, 1, 1
>>> if x == 1 and y == 1 and z == 1:
... print("Passed")
...
Passed
>>> if all((x, y, z)):
... print("Passed")
...
Passed
3. Sorting a dict by values.
Question: How to sort a dict by values?
Answer: Using the sorted
method along with operator.itemgetter
or any ordinary function as a key.
>>> dict1 = {'a': 4, 'b': 3, 'c': 2, 'd': 1}
>>> dict1_sorted = dict(sorted(dict1.items(), key=lambda item:item[1]))
>>> dict1_sorted
{'d': 1, 'c': 2, 'b': 3, 'a': 4}
>>> import operator
>>> dict1_sorted = dict(sorted(dict1.items(), key=operator.itemgetter(1)))
>>> dict1_sorted
{'d': 1, 'c': 2, 'b': 3, 'a': 4}
4. The get
method on dicts and its "default" argument.
Question: How to fetch a dict value given a key?
Answer: Using the get
method.
>>> name_for_userid = {123: "Alice", 432: "Bob"}
>>> print(f"Hello {name_for_userid.get(123, 'there')}!")
Hello Alice!
>>> print(f"Hello {name_for_userid.get(999, 'there')}!")
Hello there!
5. Namedtuples can be a great alternative to defining a class manually.
Question: What is another way to define a class?
Answer: Using collections.namedtuple
.
>>> from collections import namedtuple
>>> Car = namedtuple('Car', 'color mileage')
>>> my_car = Car('red', 312.4)
>>> my_car
Car(color='red', mileage=312.4)
>>> my_car.color
'red'
>>> my_car.mileage
312.4
6. Cool python imports.
Question: Are there any easter eggs in python?
Answer: Yes.
>>> import antigravity
>>> import this
7. Pretty print a dict.
Question: How to print a dict with indentation?
Answer: Using json.dumps
method.
>>> import json
>>> dict1 = {'b': 2, 'a': 1, 'c': 4}
>>> print(json.dumps(dict1, indent=4, sort_keys=True))
{
"a": 1,
"b": 2,
"c": 4
}
8. Function argument unpacking in python.
Question: How to pass multiple arguments at once to a given function?
Answer: Using the unpack *
operator.
>>> def my_func(a, b, c):
... print(a, b, c)
...
>>> dict1 = {'a': 1, 'b': 3, 'c': 4}
>>> my_func(*dict1)
a b c
>>> my_func(**dict1)
1 3 4
>>>
9. Using the built-in timeit
module to measure the performance of your code.
Question: How to measure the execution time of your code?
Answer: Using the timeit
module.
>>> import timeit
>>> code_snippet = "for _ in range(1000): ..."
>>> timeit.timeit(code_snippet, number=10_000)
0.1994824110006448
10. In-place value swapping.
Question: How to swap values in python?
Answer: Using the tuple notation ,
.
>>> a = 1
>>> b = 2
>>> a, b = b, a
>>> a, b
(2, 1)
11. Use "is" instead of "==" to test for object identity.
Question: How to test identities of two objects?
Answer: Using the is
operator.
>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True
12. Python built-in HTTP server.
Question: How to preview a website?
Answer: Using the http.server
method.
➜ ~ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
127.0.0.1 - - [08/Sep/2022 21:46:01] "GET / HTTP/1.1" 200 -
This will serve the current directory on http://localhost:8000
or http://127.0.0.1:8000
.
13. Use list comprehensions. They're more concise and easier to read.
Question: How to filter values in python?
Answer: Using a list comprehension.
# Filter odd values.
>>> a = [x * x for x in range(10) if not x % 2]
>>> a
[0, 4, 16, 36, 64]
14. Type annotations.
Question: How to explicitly declare a type for a given variable?
Answer: Using type annotations.
>>> def add(a: int, b: int) -> int:
... return a + b
...
15. Finding the most common elements in an iterable.
Question: How to find the n
most frequent items in an iterable?
Answer: Using the collections.Counter.most_common
method.
>>> c = collections.Counter("HelloWorld")
>>> c
Counter({'l': 3, 'o': 2, 'H': 1, 'e': 1, 'W': 1, 'r': 1, 'd': 1})
>>> c.most_common(2)
[('l', 3), ('o', 2)]
# they have the most counts as n=2 in this case.
16. Generate permutations for an iterable.
Question: How to generate permutations for a given iterable?
Answer: Using the itertools.permutations
method.
>>> import itertools
>>> for p in itertools.permutations('abc'):
... print(p)
...
('a', 'b', 'c')
('a', 'c', 'b')
('b', 'a', 'c')
('b', 'c', 'a')
('c', 'a', 'b')
('c', 'b', 'a')
17. __str__
vs __repr__
.
Question: When to use __str__
and __repr__
?
Answer: __repr__
is for developers, __str__
is for customers.
>>> import datetime
>>> today = datetime.datetime.utcnow()
>>> today
datetime.datetime(2022, 9, 8, 19, 5, 39, 446208)
>>> str(today)
'2022-09-08 19:05:39.446208'
>>> repr(today)
'datetime.datetime(2022, 9, 8, 19, 5, 39, 446208)'
>>> today
datetime.datetime(2022, 9, 8, 19, 5, 39, 446208)
18. Use @classmethod
and @staticmethod
decorators on class methods as needed.
Question: What is the difference between classmethod
and staticmethod
?
>>> class A:
... def foo(self, x):
... print(f"executing foo({self}, {x})")
... @classmethod
... def class_foo(cls, x):
... print(f"executing class_foo({cls}, {x})")
... @staticmethod
... def static_foo(x):
... print(f"executing static_foo({x})")
...
>>> a = A()
Answer: With classmethod
, the class of the object instance is implicitly passed as the first argument instead of self.
>>> a.foo(1)
executing foo(<__main__.A object at 0x7f90ff34cf70>, 1)
staticmethod
don't have access to cls
(the class) nor self
(the instance). They behave like plain functions except that you can call them from an instance or the class:
>>> a.static_foo(1)
executing static_foo(1)
>>> A.static_foo('hi')
executing static_foo(hi)
19. Lambda functions.
Question: When to use lambda functions?
Answer: To represent a mathematical function of some sort.
>>> f = lambda x, y: x+y
>>> f(2,3)
5
20. Working with IP addresses.
Question: How to store an IP address?
Answer: Using the ipaddress
module.
>>> import ipaddress
>>> ipaddress.ip_address('192.168.1.2')
IPv4Address('192.168.1.2')
>>> ipaddress.ip_address('::1')
IPv6Address('::1')
21. Accessing class and function names at runtime.
Question: How to access class and function names at runtime?
Answer: Using the __name__
method.
>>> from collections import namedtuple
>>> Car = namedtuple('Car', 'color mileage')
>>> car = Car(color='red', mileage=123.12)
>>> car.__class__.__name__
'Car'
>>>
22. Class inheritance and the issubclass
built-in function.
Question: How to check class inheritance?
Answer: Using the issubclass
module.
>>> class Parent:
... ...
...
>>> class Child(Parent):
... ...
...
>>> issubclass(Child, Parent)
True
23. Unicode variable names.
Question: Is Unicode variable names allowed in python?
Answer: Yes.
>>> á = 'a'
>>> ª = 1
>>> ❤️ = 'Python 2' # not allowed
File "<stdin>", line 1
❤️ = 'Python 2'
^
SyntaxError: invalid character '❤️' (U+1F4A9)
24. globals
and locals
.
Question: What is the difference between globals
and locals
?
Answer: globals
gets all global variables in the current scope.
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None,
.
.
.
locals
gets all local variables in the current scope.
>>> locals()
{'__name__': '__main__', '__doc__': None, '__package__': None,
.
.
.
25. faulthandler
module.
Question: What does faulthandler
do?
Answer: Display tracebacks even when python crashes, segfault.
>>> import faulthandler
>>> faulthandler.enable()
26. else
with for
and while
loops.
Question: What does else
do with a loop?
Answer: Its scope runs only if the loop ran to completion without hitting a break
statement.
>>> for i in range(10):
... print(i)
... if i == 8:
... break # termination, no else
... else:
... print("after for loop")
...
0
1
2
3
4
5
6
7
8
27. Pythonic way to check if all elements are equal in a list.
Question: How to check if all elements are equal in a list?
Answer: using the set
method to check for unique values.
>>> lst = [1, 1, 1]
>>> len(set(lst)) == 1
True
28. contextlib.suppress
.
Question: How to ignore specific exceptions?
Answer: using the contextlib
module.
>>> import contextlib, os
>>> with contextlib.suppress(FileNotFoundError):
... os.remove('file_name.txt')
...
>>>
29. Forced keyword-only parameters.
Question: How to force keyword-only arguments?
Answer: using the *
operator.
>>> def f(a, b, *, c='x', d='y'):
... return "Hello"
...
>>> f(1, 2, 'p', 'q')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() takes 2 positional arguments but 4 were given
>>> f(1, 2, c='p', d='q')
'Hello'
30. Multiple sets of kwargs.
Question: How to pass multiple sets of keyword arguments?
Answer: using the unpack **
operator.
>>> def f(a, b, c, d):
... ...
...
>>> x = {'a': 1, 'b': 2}
>>> y = {'c': 3, 'd': 4}
>>> f(**x, **y)
>>>
These are all the things I've learned from subscribing to the Real Python mailing list. If you're looking for a more in-depth look at Python, I highly recommend checking out My repo; you might be surprised at what you learn!
wiseaidev / awesome-python
📚 Awesome Python Resources (mostly PyCon).
📜 Summary
A curated list of python tutorials, notes, slides deck, files related to pycon talks, and a handful list of books that are worth reading. This repository can be used as a reference documentation for mastering the python programming language and other related content like frameworks and such.
This repository serves three primary roles:
-
Sharing an opinionated list of python videos.
-
Sharing notes driven by the awesome community.
-
Sharing a handful list of books that can play a significant role in honing your python skills.
If you are looking for a way to contribute to the project, please refer to the
Guideline
.
Don't forget to slap that ⭐ button an odd number of times ;-)
Currently maintained by
Mahmoud Harmouch
.
👉 Table Of Content (TOC).
-
Python Talks
1.1. Novice Level - Core
1.2. Intermediate Level - Core
1.3. Generic
1.4. Python 2 and Python 3…
Cover Image by Gerd Altmann from Pixabay.
Top comments (8)
By coincidence I recently encountered the reason why item 7 "Pretty print a dict." is not reliable.
i.e. Answer: Using json.dumps method.
This will fail when the items in the dictionary are not things that can be expressed as JSON. The two I encountered were enumerations and tuples.
Actually, I don't like to use this method, but rather engineer my own thing. For instance, at some point in the past, i created these handy functions:
Usage:
It seems like, over the years, I developed a hate relationship with the DRY principle. Anyways, I hope you find it useful. Cheers mate!
json.dumps() will represent tuples as JSON lists. But there are certainly other Python types that json.dumps() can't handle, like datetimes
The pprint ("pretty-print") module handles all of those. So, instead of json.dumps() you can use pprint.pprint()
Well it simply didn't in the environment that I was using, instead it crashed on the tuple. To be clear, the tuple was being used as a key in the Python dictionary, something that Python allows but I'm guessing has no equivalence in JSON.
Yes, JSON keys need to be strings.
In any case, pprint was introduced to the stdlib specifically to handle pretty-printing of Python values, but I don't run across many people who seem to know about it.
post script - as it happened I was curious enough about JSON versus data structures to try getting it to handle something more than just text keys. So I wrote an experiment about using enumerations - see:
Check orjson, faster and better json handling
There is a library to solve that, check orjson, its faster, it parses more types, check it out