Équivalences

English here!

Vous avez un code qui marche, et vous voulez le rendre plus joli, plus lisible. C'est ce qu'on appelle du refactoring. Voici une liste de transformations disponibles pour vous aider dans cette tâche. Vous pouvez bien sûr choisir de faire la transformation ou non. Un "→" indique que ce code sera probablement plus clair (selon moi). Un "↔" indique que la clarté dépendra du contexte (il n'y en n'a pas un qui soit à priori plus clair).

inverser if/else

English here!

if CONDITION:
    A
else:
    B
# ↔
if not(CONDITION):
    B
else:
    A

exemple 1

if a == 5:
    print("hello")
else:
    waw = 2
# ↔ (inverser if/else)
if not(a == 5):
    waw = 2
else:
    print("hello")
# ↔ (not == ↔ !=)
if a != 5:
    waw = 2
else:
    print("hello")

sinon ne rien faire

English here!

if CONDITION:
    A
else:
    pass  # ne rien faire
# → 
if CONDITION:
    A

exemple 1

if a != 5:
    print("hello")
else:
    pass  # ne rien faire
# → ("sinon ne rien faire" est inutile)
if a != 5:
    print("hello")

exemple 2

if a == 5:
    pass  # ne rien faire
else:
    print("hello")
# → (inverser if/else)
if a != 5:
    print("hello")
else:
    pass  # ne rien faire
# → ("sinon ne rien faire" est inutile)
if a != 5:
    print("hello")
    

simplifier not (lois de De Morgan)

English here!

# De Morgan sur "et"
if not(A and B):
    ...
# ↔
if (not A) or (not B):
    ...

# De Morgan sur "ou"
if not(A or B):
    ...
# ↔
if (not A) and (not B):
    ...

exemple 1

if not(a > 10 or a == 5):
    print('hello')
# → (De Morgan)
if a <= 10 and a != 5:
    print('hello')
    

exemple 2

if a > 10 or a == 5:
    pass
else:
    print('hello')
# → (inverser if/else)
if not(a > 10 or a == 5):
    print('hello')
else:
    pass
# → ("sinon ne rien faire" est inutile)
if not(a > 10 or a == 5):
    print('hello')
# → (De Morgan)
if a <= 10 and a != 5:
    print('hello')

if variable

English here!

if CONDITION:
    x = A
else:
    x = B
# →
x = A if CONDITION else B
# →
x = (A if CONDITION else B)
# →
x = (A if CONDITION else
     B)

exemple

if a == 5:
    c = 2
else:
    c = 0
# → ("if en une ligne" aussi appelé "l'opérateur ternaire" ou le "if fonctionnel")
c = (5 if a == 5 else 0)
# ↔ (parenthèses non nécessaires)
c = 5 if a == 5 else 0

if elif cascade on variable

English here!

if CONDITION:
    x = A
elif CONDITION_2:
    x = B
elif CONDITION_3:
    x = C
else:
    x = D
# → 
x = (A if CONDITION else
     B if CONDITION_2 else
     C if CONDITION_3 else
     D)

exemple

if a == 5:
    c = 8
elif a == 2:
    c = 4
elif a < 0:
    c = 1
else:
    c = 0
# → (if fonctionnel)
c = (8 if a == 5 else
     4 if a == 2 else
     1 if a < 0 else
     0)

renaming

English here!

Vous pouvez renommer une variable pour lui donner un nom plus explicite :

e = v * t
i = e / 2.56
# →
distance = vitesse * temps
distance_pouces = distance / 2.56

Généralement les noms de variables de quelques lettres sont trop court (sauf dans des expressions mathématiques ou des noms de variables connues comme le "i" dans une boucle) et des variables avec plus de trois vrais mots ont un nom trop long (un commentaire à la création de la variable sera sûrement plus clair).

inline variable

English here!

x = ...
operation(x)
# → (à condition que x n'est utilisé qu'une fois)
operation(...)

exemple

x = taille + 1  # x dépend de la taille
y = taille - 1  # y dépend de la taille
le_coefficent = x + 2 * y  # on calcule le coefficent avec la formule linéaire
print(le_coefficent)       # on l'affiche

# ↔ (inline variable "le_coefficent")
x = taille + 1  # x dépend de la taille
y = taille - 1  # y dépend de la taille
print(x + 2 * y)  # on affiche le résultat de la formule linéaire

# ↔ (inline variables "x" and "y")
print((taille + 1) + 2 * (taille - 1))  # on affiche le résultat de la formule linéaire en fonction de la taille

boolean return

English here!

def f(...):
    ...
    if CONDITION:
        return True
    else:
        return False
# →
def f(...):
    ...
    return CONDITION

exemple 1

def est_pair(x):
    if x % 2 == 0:    # si le reste de la division par deux vaut 0
        return True   # Vrai, le nombre est pair
    else:             # sinon
        return False  # Faux, le nombre n'est pas pair
# → (boolean return)
def est_pair(x):
    return x % 2 == 0  # x est pair ssi le reste de la division par deux vaut 0
# :
if est_pair(4):
    ...
    

exemple 2

def voyelle(x):
    if x == 'a' or x == 'e' or x == 'i' or x == 'o' or x == 'u':
        return True
    else:
        return False
# → (boolean return)
def voyelle(x):
    return x == 'a' or x == 'e' or x == 'i' or x == 'o' or x == 'u'  # x est une voyelle ssi x vaut 'a', 'e', 'i', 'o', ou 'u'
# :
if voyelle('a'):  # si 'a' est une voyelle
    ...

== True

English here!

# avec
def est_pair(x):
    if x % 2 == 0:  # si le reste de la division par deux vaut 0
        return True
    else:
        return False
# :
if est_pair(4) == True:  # si la fonction est_pair renvoie True
    ...
# →
if est_pair(4):  # si 4 est pair
    ...

or

English here!

if CONDITION:
    A
elif CONDITION_2:
    A  # même A
# →
if CONDITION or CONDITION_2:
    A
    

exemple

if a == 5:
    x = 2
elif a > 10:
    x = 2
# → (or)
if a == 5 or a > 10:
    x = 2
    

or else

English here!

if CONDITION:
    A
elif CONDITION_2:
    A  # même A
else:
    B
# →
if CONDITION or CONDITION_2:
    A
else:
    B

exemple

if a == 5:
    x = 2
elif a > 10:
    x = 2
else:
    print('error')
# → (or)
if a == 5 or a > 10:
    x = 2
else:
    print('error')

or return

English here!

def f(...):
    ...
    if CONDITION:
        return True
    if CONDITION_2:
        return True
    return False
# →
def f(...):
    ...
    return CONDITION or CONDITION_2
# ↔
def f(...):
    ...
    return (CONDITION
            or CONDITION_2)

exemple

def interessant(x):
    if x > 10:  # si x > 10
        return True  # il est intéressant
    if x == 5:  # si x == 5
        return True  # il est intéressant
    return False  # sinon, il n'est pas intéressant
# → (or return)
def interessant(x):
    return x > 10 or x == 5  # x est intéressant si il est > 10 ou == 5

and

English here!

if CONDITION:
    if CONDITION_2:
        A
# →
if CONDITION and CONDITION_2:
    A

exemple

if a == 5:
    if a > 10:
        print('waw')
# → (and)
if a == 5 and a > 10:
    print('waw')

and else

English here!

if CONDITION:
    if CONDITION_2:
        A
    else:
        B
else:
    B  # même b
# →
if CONDITION and CONDITION_2:
    A
else:
    B

exemple

if a == 5:
    if b > 10:
        waw = 2 
    else:
        print('error')
else:
    print('error')
# → (and)
if a == 5 and b > 10:
    waw = 2
else:
    print('error')

if return

English here!

def f(...):
    ...
    if CONDITION:
        return X
    ...
# ↔
def f(...):
    ...
    if CONDITION:
        return X
    else:
        ...

exemple

def f(x):
    if x < 0:
        return -1
    else:
        y = x + 2
        z = y ** 2
        return z
# → (if return)
def f(x):
    if x < 0:
        return -1
    y = x + 2
    z = y ** 2
    return z

Je fais généralement ça quand le "if" est vraiment court comme un simple "return". Souvent, ce sont des cas particuliers ou des cas de base, le code du bas est plus intéressant.

for if return True (∃)

English here!

# Voici comment on code un "∃"
def f(...):
    ...
    for x in L:
        if condition:  # ce "if" n'a PAS de "else"
            return True
    return False
# → (en python, il y a "all")
def f(...):
    ...
    return any(condition for x in L)
# ↔
def f(...):
    ...
    return any(condition
               for x in L)

# Note: en python, il y a aussi le for...else mais peu de gens l'utilisent

exemple

def contient_un_negatif(L):
    for x in L:  # pour tous les élements de la liste
        if x < 0:  # s'il est < 0
            return True  # la liste contient_un_negatif
    return False  # au final, c'est qu'elle n'en contient pas
# → (any)
def contient_un_negatif(L):
    return any(x < 0 for x in L)

Qui se lira Une liste L contient un négatif si...

for if return False (∀)

English here!

# Voici comment on code un "∀"
def f(...):
    ...
    for x in L:
        if condition:  # ce if n'a PAS de "else"
            return False
    return True
# → (en python, il y a "all")
def f(...):
    return all(not condition for x in L)
# ↔
def f(...):
    return all(not condition
               for x in L)

# Note: en python, il y a aussi le for...else mais peu de gens l'utilisent

exemple

def totalement_positive(L):
    for x in L:  # pour tous les élements de la liste
        if x < 0:  # s'il est < 0
            return False  # la liste n'est pas totalement_positive
    return True  # au final, c'est que la liste est totalement_positive
# → (all)
def totalement_positive(L):
    return all(x >= 0 for x in L)

Qui se lira Une liste L est totalement_positive si...

not ∀/∃ (lois de De Morgan)

English here!

# De Morgan sur "∀"
not all(condition for x in L)
# →
any(not condition for x in L)

# De Morgan sur "∃"
not any(condition for x in L)
# →
all(not condition for x in L)

exemple

if not all(x >= 0 for x in L):  # si on n'a pas tous les nombres >= 0
    ...
# → (if non empty)
if any(x < 0 for x in L):  # c'est qu'il existe un nombre < 0
    ...

Attention: cette transformation ne marche pas si L est vide !

for if return else return

English here!

# Voici comment on code une recherche linéaire
def f(...):
    for x in L:
        if condition:
            return a
    return b
# → (en python, il y a "next")
def f(...):
    return next((a for x in L if condition), b)
# ↔
def f(...):
    return next((a for x in L if condition),
                b)

# Note: en python, il y a aussi le for...else mais peu de gens l'utilisent

exemple

Le super_nombre d'une liste est le premier x dans la liste tel que x > 10 :

def super_nombre(L):
    for x in L:  # pour tous les élements de la liste
        if x > 10:  # s'il est > 10
            return x  # c'est le super nombre de cette liste
    return 0  # il n'y a pas de super nombre, on renvoie 0
# →
def super_nombre(L):
    return next((x for x in L if x > 10), 0)

for append

English here!

L = []
for x in iterable:
    L.append(e)
# →
L = [e for x in iterable]

for append f(x)

English here!

L = []
for x in iterable:
    L.append(f(x))
# →
L = list(map(f, iterable))
# ↔
L = [f(x) for x in iterable]

for if append

English here!

L = []
for x in iterable:
    if condition:
        L.append(e)
# →
L = [e for x in iterable if condition]

for if f(x) append x

English here!

L = []
for x in iterable:
    if f(x):
        L.append(x)
# →
L = list(filter(f, iterable))
# ↔
L = [x for x in iterable if f(x)]

itérer un générateur (python)

English here!

for x in list(generateur):
    ...
# →
for x in generateur:
    ...

exemple 1

for x in list(map(f, L)):  # map, filter, zip...
    ...
# →
for x in map(f, L):
    ...

exemple 2

# avec
def operation(x):
    return (x + 1) * 2 - x
# :
for x in list(map(operation, [1,2,3])):
    print(x)
# →
for x in map(operation, [1,2,3]):
    print(x)

sum

English here!

exemple

s = 0
for x in L:
    s += a
# → (sum)
s = sum(a for x in L)

# techniquement, "sum" est un cas particulier de "reduce" mais "reduce" est peu utile en python

in tuple (python)

English here!

exemple

if x == 'a' or x == 'e' or x == 'i' or x == 'o' or x == 'u':
    ...
# → (in)
if x in ('a', 'e', 'i', 'o', 'u'):
    ...

# c'est un cas particulier de recherche linéaire dans une liste