@Pythonetc juin 2019


Ceci est la onzième sélection de conseils et de programmation Python de mon flux @pythonetc.

Collections précédentes


Le 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 

Source: https://habr.com/ru/post/fr458686/


All Articles