@ Pythonetc Juni 2019


Dies ist die elfte Auswahl an Python-Tipps und -Programmierungen aus meinem @ pythonetc-Feed.

Frühere Sammlungen


Das Zeichen \ in einer regulären Zeile hat eine besondere Bedeutung. \t ist ein Tabulatorzeichen, \r ist ein Zeilenumbruch und so weiter.

Um dieses Verhalten zu deaktivieren, können Sie unformatierte Zeichenfolgen verwenden. Dann wird r'\t' nur noch ein Backslash und t .

Offensichtlich können Sie ' inside r'...' nicht verwenden. Und obwohl diese Einschränkung mit \ umgangen werden kann, bleibt die Zeile \ dennoch bestehen:

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


Listengeneratoren können mehr als ein Paar von for und if Ausdrücken enthalten:

 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)] 

Darüber hinaus kann jeder Ausdruck in for und if alle zuvor definierten Variablen verwenden:

 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) ] 

Sie können mischen, if und for wie Sie möchten:

 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) ] 


Mit der sorted Funktion können sorted benutzerdefinierte Sortiermethoden angeben. Dies geschieht mit dem key , das beschreibt, wie die ursprünglichen Werte für einen späteren Vergleich konvertiert werden:

 >>> 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'}] 

Leider unterstützen nicht alle Bibliotheken, die mit Vergleichen arbeiten, das Hauptargument. Von denen, die gemunkelt werden, können heapq (teilweise Unterstützung) und bisect (keine Unterstützung) erwähnt werden.

In dieser Situation gibt es zwei Möglichkeiten. Sie können benutzerdefinierte Objekte verwenden, die einen ordnungsgemäßen Vergleich unterstützen:

 >>> 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'] 

Möglicherweise müssen Sie jedoch mehrere Versionen solcher Klassen erstellen, da Objekte auf unterschiedliche Weise verglichen werden können. Dies kann unpraktisch sein, daher gibt es einen zweiten Weg.

Anstatt benutzerdefinierte Objekte zu erstellen, können Sie Tupel (a, b) , wobei a der zu vergleichende Wert (Priorität) und b der ursprüngliche Wert ist:

 >>> 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'] 


Der Unterschied zwischen der Definition und dem Funktionsgenerator besteht im Vorhandensein des Schlüsselworts yield im Funktionskörper:

 In : def f(): ...: pass ...: In : def g(): ...: yield ...: In : type(f()) Out: NoneType In : type(g()) Out: generator 

Dies bedeutet, dass Sie Folgendes tun müssen, um einen leeren Generator zu erstellen:

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

Aber da die yield from einfache Iteratoren unterstützt, d. H. Eine schönere Version:

 def g(): yield from [] 


In Python können Sie Ketten von Vergleichsoperatoren erstellen:

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

Solche Ketten müssen nicht mathematisch korrekt sein, Sie können > und < mischen:

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

== Operatoren werden ebenfalls unterstützt. is und in :

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

Jeder Operator gilt für zwei benachbarte Operanden. a OP1 b OP2 c streng äquivalent zu (a OP1 b) AND (b OP2 c) . Ein Vergleich von a und c nicht durchgeführt:

 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) 

Ergebnis:

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

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


All Articles