Trucs et astuces de ma chaîne Telegram @pythonetc, juin 2019


C'est une nouvelle sélection de trucs et astuces sur Python et la programmation de mon canal Telegram @pythonetc.

Publications précédentes


Le symbole \ dans la chaîne régulière a une signification spéciale. \t est un caractère de tabulation, \r est un retour chariot, etc.

Vous pouvez utiliser des chaînes brutes pour désactiver ce comportement. r'\t' est juste une barre oblique inverse et t .

Vous ne pouvez évidemment pas utiliser ' inside r'...' . Cependant, il peut toujours être échappé par \ , mais \ est conservé dans la chaîne:

 >>> print(r'It\'s insane!') It\'s insane! 


Les compréhensions de liste peuvent contenir plusieurs clauses 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 dans for et if peut utiliser toutes les variables définies avant:

 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 s et for s 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 vous permet de fournir une méthode personnalisée pour le tri. Cela se fait avec l'argument key , qui décrit comment convertir les valeurs d'origine en valeurs réellement comparées:

 >>> 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 qui fonctionnent avec la comparaison ne prennent pas en charge cet argument key . Les exemples notables sont heapq (prise en charge partielle) et bisect (pas de prise en charge).

Il y a deux façons de gérer la situation. La première consiste à utiliser des objets personnalisés qui prennent en charge la 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 il existe plusieurs façons de comparer les objets. Cela peut être fastidieux, mais peut être facilement résolu par la deuxième façon.

Au lieu de créer des objets personnalisés, vous pouvez utiliser des tuples (a, b)a est la valeur à comparer (alias prioirty) 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 de fonction et la définition de générateur 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 faire quelque chose comme ceci:

 In : def g(): ...: if False: ...: yield ...: In : list(g()) Out: [] 

Cependant, étant yield from que le yield from supports d'itérateurs simples, cette version la plus belle serait la suivante:

 def g(): yield from [] 


En Python, vous pouvez chaîner des opérateurs de comparaison:

 >>> 0 < 1 < 2 True >>> 0 < 1 < 0 False 

De telles chaînes ne doivent pas être mathématiquement valides, vous pouvez mélanger > et < :

 >>> 0 < 1 > 2 False >>> 0 < 1 < 2 > 1 > 0 True 

D'autres opérateurs tels que == , is et in sont également pris en charge:

 >>> [] is not 3 in [1, 2, 3] True 

Chaque opérateur est appliqué aux deux opérandes les plus proches. a OP1 b OP2 c est strictement égal à (a OP1 b) AND (b OP2 c) . Aucune comparaison entre a et c n'est implicite:

 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) 

Sortie:

 1 < 2 2 <= 3 3 == 3 True 

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


All Articles