Dies ist die zehnte Sammlung von Python-Tipps und -Programmierungen aus meinem @ pythonetc-Feed.
Vorherige Auswahl .
0_0
0_0
ist ein völlig korrekter Ausdruck in Python.
Liste mit Keine sortieren
Das Sortieren einer Liste mit den Werten
None
kann eine entmutigende Aufgabe 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, alle None zu löschen und sie nach dem Sortieren zurückzugeben (je nach Aufgabe an den Anfang oder an das Ende 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]
Aber es ist unpraktisch. Verwenden Sie besser 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]
Wenn es sich um Typen handelt, für die Unendlichkeit nicht akzeptabel ist, können Sie die 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]
Rufen Sie random.seed () auf
Wenn Sie den Prozess verzweigen, wird der von Ihnen verwendete zufällige Startwert in alle resultierenden Prozesse kopiert. Infolgedessen kann das gleiche "zufällige" Ergebnis in ihnen erzeugt werden.
Um dies zu vermeiden, müssen Sie
random.seed()
in jedem Prozess manuell aufrufen. Wenn Sie jedoch das
multiprocessing
Modul verwenden, erledigt es
dies für Sie.
Zum 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()
Holen Sie sich so etwas:
4 4 4 5 5 1 4 1 3 3 2 2 2 2 2
Wenn Sie Python 3.7 und höher verwenden, können Sie dank des neuen at_fork-Hooks
dasselbe mit
os.fork
.
Der obige Python 3.7-Code liefert dieses Ergebnis:
1 2 2 1 5 4 4 4 5 5 2 4 1 3 1
Addition zu 0
Auf den ersten Blick scheint die
sum([a, b, c])
äquivalent zu
a + b + c
, obwohl das Äquivalent tatsächlich
0 + a + b + c
. Daher kann dieser Ausdruck nicht mit Typen funktionieren, 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
zum Hinzufügen von
float
und
int
Typen, kann jedoch auch mit anderen benutzerdefinierten Typen verwendet werden. Er weigert sich jedoch,
bytes
,
bytearray
und
str
hinzuzufügen, da
join
zu diesem Zweck dient:
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ändigung in Jupyter Notebook
Mit der Methode
_ipython_key_completions_
können
_ipython_key_completions_
die Indexvervollständigung in einem Jupyter-Notizbuch anpassen. Auf diese Weise können Sie steuern, was auf dem Bildschirm angezeigt wird, wenn Sie nach
d["x
:
d["x
Tabulatortaste drücken.

Beachten Sie, dass die Methode die zu durchsuchende Zeichenfolge nicht als Argument empfängt.