[Python] Petites fonctions qui vont bien
Il existe plein de petites fonctions en Python qui permettent de s’éviter des boucles inutiles.
Lecture d’un fichier contenant des nombres
Lorsqu’un fichier d’entrée est une liste de nombres séparés par un saut de ligne, le moyen le plus simple pour récupérer un tableau de valeurs numériques est :
numbers = [ int(x) for x in open("input.txt","r") ]
min / max / sum
Ces fonctions permettent de récupérer facilement le minimum, le maximum et la somme des éléments d’un iterable.
input = [4, 5, 3, 1, 2]
min(input)
# returns 1
max(input)
# returns 5
sum(input)
# returns 15
any / all
Ces fonctions permettent de savoir facilement si au moins un élément d’un itérable est vrai (any
) ou si tous les éléments d’un itérable sont vrais (all
).
input = [4, 5, 3, 1, 2]
# Est-ce qu'il y a au moins un élément pair ?
any(x % 2 == 0 for x in input)
# Returns True
# Est-ce tous les éléments sont pair ?
all(x % 2 == 0 for x in input)
# Returns False
Lambda
Au lieu de définir une fonction, on peut le faire en une ligne avec une lambda.
map / filter / reduce
TODO
Generators
Certaines fonctions qui génèrent des listes peuvent prendre beaucoup de mémoire.
Exemple :
def first_n(n):
'''Build and return a list'''
num, nums = 0, []
while num < n:
nums.append(num)
num += 1
return nums
sum_of_first_n = sum(first_n(1000000))
A l’exécution, la liste complète est chargée en mémoire.
On peut remplacer la fonction par un generator :
# a generator that yields items instead of returning a list
def firstn(n):
num = 0
while num < n:
yield num
num += 1
sum_of_first_n = sum(firstn(1000000))
Le generator retournera les éléments 1 par 1, à la demande.
Set
Namedtuple
Petite collection qui permet de stocker des tuples nommés.
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(11, y=22) # instantiate with positional or keyword arguments
p[0] + p[1] # indexable like the plain tuple (11, 22)
# Returns 33
x, y = p # unpack like a regular tuple
x, y
# Returns (11, 22)
p.x + p.y # fields also accessible by name
# Returns 33
p._asdict() # convert into dict
# Returns {'x': 11, 'y': 22}
Plus d’infos sur https://docs.python.org/3/library/collections.html#collections.namedtuple
Les namedtuples ne sont pas mutables. Si on souhaite un objet modifiable on peut utiliser une librairie externe recordclass
:
from recordclass import recordclass
Point = recordclass('Point', 'x y')
p = Point(1, 2)
p
# Returns Point(x=1, y=2)
print(p.x, p.y)
# Returns 1 2
p.x += 2
p.y += 3
print(p)
# Returns Point(x=3, y=5)