DEV Community

Cover image for 30 PyTricks I've Learned By Joining the Real Python Mailing List.
Mahmoud Harmouch
Mahmoud Harmouch

Posted on • Edited on

30 PyTricks I've Learned By Joining the Real Python Mailing List.

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}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode

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!
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

6. Cool python imports.

Question: Are there any easter eggs in python?

Answer: Yes.

>>> import antigravity
>>> import this
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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
>>> 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 -
Enter fullscreen mode Exit fullscreen mode

This will serve the current directory on http://localhost:8000 or http://127.0.0.1:8000.

server

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]
Enter fullscreen mode Exit fullscreen mode

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
... 
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

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')
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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')
Enter fullscreen mode Exit fullscreen mode

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'
>>> 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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,
.
.
.
Enter fullscreen mode Exit fullscreen mode

locals gets all local variables in the current scope.

>>> locals()
{'__name__': '__main__', '__doc__': None, '__package__': None,
.
.
.
Enter fullscreen mode Exit fullscreen mode

25. faulthandler module.

Question: What does faulthandler do?

Answer: Display tracebacks even when python crashes, segfault.

>>> import faulthandler
>>> faulthandler.enable()
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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')
...
>>>
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

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)
>>> 
Enter fullscreen mode Exit fullscreen mode

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!

GitHub logo wiseaidev / awesome-python

📚 Awesome Python Resources (mostly PyCon).

Awesome Python Awesome


📜 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:

  1. Sharing an opinionated list of python videos.

  2. Sharing notes driven by the awesome community.

  3. 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).

  1. 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)

Collapse
 
geraldew profile image
geraldew

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.

Collapse
 
wiseai profile image
Mahmoud Harmouch

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:

def indent(string: str, num_spaces: int) -> str:
    indent_str: str = " " * num_spaces
    return "\n".join(indent_str + line for line in string.split("\n")[:-1]) + "\n"

def pretty_dict(dict_: dict[str, str], num_spaces: int) -> str:
  if not isinstance(dict_, dict):
    return repr(dict_)
  rep = []
  for key, val in dict_.items():
    rep.append(f"{key}: {pretty_dict(val, num_spaces)},\n")
  if rep:
    return f'{{\n{indent("".join(rep), num_spaces)}}}'
  else:
    return "{}"
Enter fullscreen mode Exit fullscreen mode

Usage:

>>> dict1 = {'b': 2, 'a': {'b': [1, 2, 3]}, 'c': list(enumerate(range(4)))}
>>> print(pretty_dict(dict1, 2))
{
  b: 2,
  a: {
    b: [1, 2, 3],
  },
  c: [(0, 0), (1, 1), (2, 2), (3, 3)],
}
Enter fullscreen mode Exit fullscreen mode

It seems like, over the years, I developed a hate relationship with the DRY principle. Anyways, I hope you find it useful. Cheers mate!

Collapse
 
tompollard61 profile image
Tom Pollard

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()

Collapse
 
geraldew profile image
geraldew

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.

Thread Thread
 
tompollard61 profile image
Tom Pollard

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.

Thread Thread
 
geraldew profile image
geraldew

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:

Collapse
 
gdledsan profile image
Edmundo Sanchez

Check orjson, faster and better json handling

Collapse
 
gdledsan profile image
Edmundo Sanchez

There is a library to solve that, check orjson, its faster, it parses more types, check it out