Es ist eine neue Auswahl von Tipps und Tricks zu Python und Programmierung von meinem Telegramm-Kanal @pythonetc.
Frühere Veröffentlichungen .
0_0
0_0 ist ein vollständig gültiger Python-Ausdruck.
Sortieren einer Liste mit Keine
Das Sortieren einer Liste mit den Werten 
None kann eine Herausforderung sein:
 In [1]: data = [ ...: dict(a=1), ...: None, ...: dict(a=-3), ...: dict(a=2), ...: None, ...: ] In [2]: sorted(data, key=lambda x: x['a']) ... TypeError: 'NoneType' object is not subscriptable 
Sie können versuchen, Nones zu entfernen und nach dem Sortieren wieder einzufügen (je nach Aufgabe bis zum Ende oder Anfang der Liste):
 In [3]: sorted( ...: (d for d in data if d is not None), ...: key=lambda x: x['a'] ...: ) + [ ...: d for d in data if d is None ...: ] Out[3]: [{'a': -3}, {'a': 1}, {'a': 2}, None, None] 
Das ist ein Schluck. Die bessere Lösung besteht darin, einen komplexeren 
key :
 In [4]: sorted(data, key=lambda x: float('inf') if x is None else x['a']) Out[4]: [{'a': -3}, {'a': 1}, {'a': 2}, None, None] 
Für Typen, für die keine Unendlichkeit verfügbar ist, können Sie stattdessen Tupel sortieren:
 In [5]: sorted(data, key=lambda x: (1, None) if x is None else (0, x['a'])) Out[5]: [{'a': -3}, {'a': 1}, {'a': 2}, None, None] 
Random.seed () aufrufen
Wenn Sie Ihren Prozess verzweigen, wird der zufällige Startwert, den Sie verwenden, prozessübergreifend kopiert. Dies kann dazu führen, dass Prozesse das gleiche "zufällige" Ergebnis erzielen.
Um dies zu vermeiden, müssen Sie 
random.seed() in jedem Prozess manuell aufrufen.
Dies ist jedoch nicht der Fall, wenn Sie das 
multiprocessing Modul verwenden, es 
erledigt genau das für Sie.
Hier ist ein Beispiel:
 import multiprocessing import random import os import sys def test(a): print(random.choice(a), end=' ') a = [1, 2, 3, 4, 5] for _ in range(5): test(a) print() for _ in range(5): p = multiprocessing.Process( target=test, args=(a,) ) p.start() p.join() print() for _ in range(5): pid = os.fork() if pid == 0: test(a) sys.exit() else: os.wait() print() 
Das Ergebnis ist so etwas wie:
 4 4 4 5 5 1 4 1 3 3 2 2 2 2 2 
Wenn Sie Python 3.7 oder 
os.fork macht os.fork dank des neuen 
at_fork .
Die Ausgabe des obigen Codes für Python 3.7 lautet:
 1 2 2 1 5 4 4 4 5 5 2 4 1 3 1 
Hinzufügen zu 0
Es sieht so aus, als ob die 
sum([a, b, c]) für 
a + b + c äquivalent ist, während sie tatsächlich 
0 + a + b + c . Das bedeutet, dass es nicht mit Typen funktionieren kann, die das Hinzufügen zu 
0 nicht unterstützen:
 class MyInt: def __init__(self, value): self.value = value def __add__(self, other): return type(self)(self.value + other.value) def __radd__(self, other): return self + other def __repr__(self): class_name = type(self).__name__ return f'{class_name}({self.value})' In : sum([MyInt(1), MyInt(2)]) ... AttributeError: 'int' object has no attribute 'value' 
Um dies zu beheben, können Sie ein benutzerdefiniertes Startelement bereitstellen, das anstelle von 
0 :
 In : sum([MyInt(1), MyInt(2)], MyInt(0)) Out: MyInt(3) 
sum ist für die Summierung von 
float und 
int Typen gut optimiert, kann jedoch jeden anderen benutzerdefinierten Typ verarbeiten. Es weigert sich jedoch, 
bytes , 
bytearray und 
str zu summieren, da der 
join für diese Operation gut optimiert ist:
 In : sum(['a', 'b'], '') ... TypeError: sum() can't sum strings [use ''.join(seq) instead] In : ints = [x for x in range(10_000)] In : my_ints = [Int(x) for x in ints] In : %timeit sum(ints) 68.3 µs ± 142 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) In : %timeit sum(my_ints, Int(0)) 5.81 ms ± 20.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 

Indexvervollständigungen im Jupiter-Notizbuch
Sie können Indexvervollständigungen in Jupyter Notebook anpassen, indem Sie die 
_ipython_key_completions_ method . Auf diese Weise können Sie steuern, was angezeigt wird, wenn Sie nach etwas wie 
d["x : 
d["x Tabulatortaste drücken.

Beachten Sie, dass die Methode die nachgeschlagene Zeichenfolge nicht als Argument erhält.