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.