Python under the hood — tips and tricks from a C++-programmers’ perspective 03

SmartLab AI
4 min readFeb 4, 2019

--

Author: Patrik Reizinger

This is the third part of an article series. You can find the first two here:

1. https://medium.com/@SmartLabAI/python-under-the-hood-tips-and-tricks-from-a-c-programmers-perspective-01-b5f96895663

2. https://medium.com/@SmartLabAI/python-under-the-hood-tips-and-tricks-from-a-c-programmers-perspective-02-b52675c7c0af

You may have wondered while reading my previous posts, why the title of this series consists the phrase tips & tricks. Today it’s time to reveal that part, so I will show you some really exciting features I use whenever I can to make my code more human readable and concise.

Disclaimer: after reading this post, you may find yourself an urge to transform your code into nice Pythonic one-liners. What you should remember: I have warned you.

Python proms (*, **)

The star operators, doesn’t matter if * or **, are a powerful (and really concise) way for manipulating lists/tuples/sets (one star) or dicts (two stars). There are two ways of usage where they will be handy. First, you can unpack containers with the usage of these operators — the concept may seem similar to the dereference operator in C++, but as you recall, Python is not the language for black pointer magic. I.e., if you want to merge two lists, you can do it the following way:

# list -the same for sets (use {} ) and tuples (use () )a = [1, 2, 3]
b = [3, 4, 5]
c = [*a, *b]
print("a = ", a) # [1, 2, 3]
print("b = ", b) # [3, 4, 5]
print("c = ", c) # [1, 2, 3, 3, 4, 5]

Beware, the merged containers will remain conform with the restrictions of the used container types, e.g. if you merge two sets, the result won’t contain duplicates of a given element.

On the other hand, you can use these operators to pass so called non-keyword and keyword arguments with * and **, respectively. This gives you the power to create functions with a variable number of arguments — do you recall that e.g. the printf function in C can take any number of arguments (the name for it is called variadic templates, a different concept, but the same result).

If you include in the function definition — I use the conventional names here, but you may pick something different, which I do not advise — *args or **kwargs, you are actually done, the (keyword) arguments are available for you in the function body.

# non-keyword argumentst = (1, 2, 3)def tt(*args):for arg in args:
print(arg+1)
tt(*t) # 2, 3, 4
###### keyword argumentsd = {'a' : 1, 'b' : 2}def dd(**kwargs):
for key, value in kwargs.items():
print("Key: ", key, " value: ", value)
dd(**d) # Prints: Key: a value: 1# Key: b value: 2

Ternary operators

Although it is functionally same as in C/C++, but it is worth knowing that Python possesses this feature too. Beware, the syntax is a bit different, basically it is a one-liner if-else clause, see the following example.

r = 5 if True else 4 # 5

List comparisons

The tricks mentioned above were cool, weren’t they? And you have not seen the best one, which allows you to filter lists as you wish and all of this practically as a one-liner. Although this technique is referred to as list comparison, you can use it also for sets.

l = list(range(10))
l_even = [x for x in l if x%2 == 0]
s_even_sq = {x**2 for x in l if x%2 == 0}
print("l = ", l) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print("l_even = ", l_even) # [0, 2, 4, 6, 8]
print("s_even_sq = ", s_even_sq) # {0, 64, 4, 36, 16}

To be or not to be

At the end comes a delicacy of Pythonic objects, which is definitely good to know if you don’t want to get nervous about seemingly perfect code.

You surely remember the part where I explained the difference between immutable and mutable objects, but a quick recap never hurts, so immutable means that the attempt to modify an object results in the allocation of a new one, reasonably mutable means that the instance can be modified.

There is a difference even in the case of comparison, for which Python has two ways, the operator == as in e.g. C++ and the is keyword. Well, they are slightly different — if you know PHP, it is similar to == vs ===.

== checks for equality, while is does it for identity. If you have an immutable object, there is no difference, because only one object with a given attribute exists (e.g. the number 5, the string “Python”), obviously several references to it may exist too.

In the mutable case == works as expected with some background from C/C++, e.g. different list with the same elements are equal, but are not always identical, only if both references were created of the same object.

a = 1
b = 1
c = a
print("a == b :", a == b) # True
print("a == c :", a == c) # True
print("a is b :", a is b) # True
print("a is c :", a is c) # True
######x = [1, 2, 3, 4, 5]
y = [1, 2, 3, 4, 5]
z = x
print("x == y :", x == y) # True
print("x == z :", x == z) # True
print("x is y :", x is y, "<--") # False
print("x is z :", x is z) # True

Code is to be found here: https://gist.github.com/rpatrik96/5411ef4c86b07c054164309d6f1381ef

--

--

SmartLab AI
SmartLab AI

Written by SmartLab AI

Deep Learning and AI solutions from Budapest University of Technology and Economics. http://smartlab.tmit.bme.hu/

No responses yet