Astuces Python en vrac (bis)


Le genre d’article qu’on fait quand on a pas d’inspiration.

Denester une list

On peut le faire avec des listes en intention imbriquées. Ou on peut utiliser cette astuce:

>>> lst = [(1,2,3), (4, 5,6)]
>>> sum(lst, ())
(1, 2, 3, 4, 5, 6)

C’est pas très performant, mais c’est très court.

deepcopy de structures de données complexes

Si vous avez des listes des dictionnaires et de tuples, faire des copies, ne peut se faire avec le signe égal, car on copie juste la référence. Le module copy permet de faire une vrai copie de la liste, mais il existe une alternative toute bête:

>>> import pickle
>>> deepcopy = lambda x: pickle.loads(pickle.dumps(x))
>>> deepcopy([[1, 2, 3], [1, 2, 3]])
[[1, 2, 3], [1, 2, 3]]

Initialiser rapidement une matrice

>>> make_matrix = lambda cols, rows: [x[:] for x in [[0] * cols] * rows]
>>> make_matrix(4, 5)
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

Ici toute l’astuce est l’utilisation de l’opérateur splat (*) qui multiplie aussi les listes. Mais pour que cela soit un succès, on initialise la première liste avec 0 qui est immutable, et on copie chaque liste obtenue avec x[:] pour ne pas multiplier les références. On obtient ainsi de vraies copies, et non des duplications de références.

Évidement si vous cherchez la performance, utilisez plutôt NumPy.

Plusieurs print sur une seule ligne

Print insère toujours un saut de ligne, et pour écrire sur la même ligne avec plusieurs appels, on doit faire sys.stdout.write. Sauf si on utilise une virgule:

print "bib",
print "bip"

Va afficher bip bip.

Tout est comparable

Il y a pas que les chiffres qui sont comparables entre eux, tous les objets le sont. Ca n’a pas toujours du sens:

>>> True > False
True
>>> True < False
False

Mais c’est utile dans certains cas, la comparaison des mots se fait par ordre alphabétique:

>>> "a" > "b"
False
>>> "abricot" < "zoophile"
True

10 thoughts on “Astuces Python en vrac (bis)

  • Soli

    Pour les gens modernes, on pensera à remplacer le statement par la fonction correspondante:

    print("bip", end=' ')
    print("bip")

    P.S dans votre exemple bib -> bip

    D’ailleurs, puisque je parle de Python3, alors qu’en 2.x il suffit d’implémenter __cmp__() pour rendre un objet “comparable”, en 3.x il faut toutes les comparaisons: __lt__(), __le__(), __eq__(), __ne__(), __gt__() et __ge__(). [la moitié peut suffire dans certains cas vu que si NotImplemented est déclenché par une comparaison en regardant le premier objet, Python réessaie avec l’autre objet]

  • Sam Post author

    J’ai fais un benchmark rapide:

    http://is.gd/aQa0NG

    Pour 100000000 répétitions, on a les résultats suivant, en secondes:

    test pickle
    3.84893393517

    test copy
    3.62741494179

    C’est kiff kiff quoi.

  • Stéphane

    Dans le dernier exemple, il ne devrait pas y avoir les signes “>>>” devant « False » et « True » car ce sont les réponses de l’interpréteur.

  • ast

    rien compris au sum(lst, ())

    ce truc là: () c’est quoi, un tuple vide ?

    et je ne vois pas de lambda

  • JeromeJ

    @ast sum additione tous les éléments de la liste donnée à 0 par défaut. Si tu ne spécifie pas le second argument tu auras une erreur car sum tentera de faire 0 + (1,2) + (3,4) et tu peux pas additioner des int et des tuples ensemble. Donc il faut dire à sum d’initialiser avec () au lieu du 0 par défaut.

  • Sam Post author

    @ast: c’est une erreur dans l’article. Il n’y a aucune lambda.

  • JeromeJ

    @Soli Pas avec functools.total_ordering tu dois juste implémenter eq et UN des autres que tu as cités.

Comments are closed.

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.