Ceci est la onzième sélection de conseils et de programmation Python de mon flux @pythonetc.
←
Collections précédentesLe caractère
\
sur une ligne régulière a une signification particulière.
\t
est un caractère de tabulation,
\r
est un saut de ligne, etc.
Pour désactiver ce comportement, vous pouvez utiliser des chaînes brutes. Alors
r'\t'
deviendra juste une barre oblique inverse et
t
.
Évidemment, vous ne pouvez pas utiliser
'
inside
r'...'
. Et bien que cette restriction puisse être contournée avec
\
, cependant, la ligne
\
restera toujours:
>>> print(r'It\'s insane!') It\'s insane!
Les générateurs de liste peuvent contenir plusieurs paires d'expressions
for
et
if
:
In : [(x, y) for x in range(3) for y in range(3)] Out: [ (0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2) ] In : [ (x, y) for x in range(3) for y in range(3) if x != 0 if y != 0 ] Out: [(1, 1), (1, 2), (2, 1), (2, 2)]
De plus, toute expression à l'intérieur
for
et
if
peut utiliser toutes les variables précédemment définies:
In : [ (x, y) for x in range(3) for y in range(x + 2) if x != y ] Out: [ (0, 1), (1, 0), (1, 2), (2, 0), (2, 1), (2, 3) ]
Vous pouvez mélanger
if
et
for
comme vous le souhaitez:
In : [ (x, y) for x in range(5) if x % 2 for y in range(x + 2) if x != y ] Out: [ (1, 0), (1, 2), (3, 0), (3, 1), (3, 2), (3, 4) ]
La fonction
sorted
permet de spécifier des méthodes de tri personnalisées. Cela se fait à l'aide de l'argument
key
, qui décrit comment convertir les valeurs d'origine pour une comparaison ultérieure:
>>> x = [dict(name='Vadim', age=29), dict(name='Alex', age=4)] >>> sorted(x, key=lambda v: v['age']) [{'age': 4, 'name': 'Alex'}, {'age': 29, 'name': 'Vadim'}]
Hélas, toutes les bibliothèques travaillant avec la comparaison ne prennent pas en charge l'argument
key
. Parmi ceux qui font l'objet de rumeurs,
heapq
(support partiel) et
bisect
(pas de support) peuvent être mentionnés.
Il y a deux façons d'aller dans cette situation. Vous pouvez utiliser des objets personnalisés qui prennent en charge une comparaison appropriée:
>>> class User: ... def __init__(self, name, age): ... self.name = name ... self.age = age ... def __lt__(self, other): ... return self.age < other.age ... >>> x = [User('Vadim', 29), User('Alex', 4)] >>> [x.name for x in sorted(x)] ['Alex', 'Vadim']
Cependant, vous devrez peut-être créer plusieurs versions de ces classes, car les objets peuvent être comparés de différentes manières. Cela peut être gênant, il existe donc une deuxième solution.
Au lieu de créer des objets personnalisés, vous pouvez utiliser des tuples
(a, b)
, dans lesquels
a
est la valeur à comparer (priorité) et
b
est la valeur d'origine:
>>> users = [dict(name='Vadim', age=29), dict(name='Alex', age=4)] >>> to_sort = [(u['age'], u) for u in users] >>> [x[1]['name'] for x in sorted(to_sort)] ['Alex', 'Vadim']
La différence entre la définition et le générateur de fonction est la présence du mot-clé
yield
dans le corps de la fonction:
In : def f(): ...: pass ...: In : def g(): ...: yield ...: In : type(f()) Out: NoneType In : type(g()) Out: generator
Cela signifie que pour créer un générateur vide, vous devez procéder comme suit:
In : def g(): ...: if False: ...: yield ...: In : list(g()) Out: []
Mais comme le
yield from
prend en charge les itérateurs simples, c'est-à-dire une version plus agréable:
def g(): yield from []
En Python, vous pouvez créer des chaînes d'opérateurs de comparaison:
>>> 0 < 1 < 2 True >>> 0 < 1 < 0 False
De telles chaînes ne doivent pas être mathématiquement correctes, vous pouvez mélanger
>
et
<
:
>>> 0 < 1 > 2 False >>> 0 < 1 < 2 > 1 > 0 True
==
opérateurs
==
sont également pris en charge.
is
et
in
:
>>> [] is not 3 in [1, 2, 3] True
Chaque opérateur s'applique à deux opérandes adjacents.
a OP1 b OP2 c
strictement équivalent à
(a OP1 b) AND (b OP2 c)
. La comparaison de
a
et
c
pas effectuée:
class Spy: def __init__(self, x): self.x = x def __eq__(self, other): print(f'{self.x} == {other.x}') return self.x == other.x def __ne__(self, other): print(f'{self.x} != {other.x}') return self.x != other.x def __lt__(self, other): print(f'{self.x} < {other.x}') return self.x < other.x def __le__(self, other): print(f'{self.x} <= {other.x}') return self.x <= other.x def __gt__(self, other): print(f'{self.x} > {other.x}') return self.x > other.x def __ge__(self, other): print(f'{self.x} >= {other.x}') return self.x >= other.x s1 = Spy(1) s2 = Spy(2) s3 = Spy(3) print(s1 is s1 < s2 <= s3 == s3)
Résultat:
1 < 2 2 <= 3 3 == 3 True