Ceci est la dixième collection de conseils et de programmation Python de mon flux @pythonetc.
Sélections précédentes .
0_0
0_0
est une expression complètement correcte en Python.
Trier la liste avec Aucun
Le tri d'une liste avec des valeurs
None
peut être une tâche ardue:
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
Vous pouvez essayer de supprimer tous les None et de les renvoyer après le tri (au début ou à la fin de la liste, selon la tâche):
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]
Mais c'est gênant. Mieux vaut utiliser une
key
plus complexe:
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]
Si nous parlons de types pour lesquels l'infini est inacceptable, vous pouvez trier les tuples:
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]
Appelez random.seed ()
Lorsque vous bifurquez le processus, la graine aléatoire que vous utilisez sera copiée dans tous les processus résultants. En conséquence, le même résultat «aléatoire» peut être généré en eux.
Pour éviter cela, vous devez appeler manuellement
random.seed()
dans chaque processus. Mais si vous utilisez le module
multiprocessing
, il le fera pour vous.
Par exemple:
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()
Obtenez quelque chose comme ça:
4 4 4 5 5 1 4 1 3 3 2 2 2 2 2
De plus, si vous utilisez Python 3.7 et supérieur, grâce au nouveau
at_fork
at_fork, vous pouvez faire de
même avec
os.fork
.
Le code Python 3.7 ci-dessus donne ce résultat:
1 2 2 1 5 4 4 4 5 5 2 4 1 3 1
Ajout à 0
À première vue, il semble que la
sum([a, b, c])
équivalente à
a + b + c
, bien qu'en fait l'équivalent soit
0 + a + b + c
. Cette expression ne peut donc pas fonctionner avec des types qui ne prennent pas en charge l'ajout à
0
:
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'
Pour résoudre ce problème, vous pouvez fournir un élément de départ personnalisé qui sera utilisé au lieu de
0
:
In : sum([MyInt(1), MyInt(2)], MyInt(0)) Out: MyInt(3)
sum
conçu pour ajouter des types
float
et
int
, bien qu'il puisse fonctionner avec n'importe quel autre type personnalisé. Cependant, il refuse d'ajouter des
bytes
,
bytearray
et
str
, car
join
à cet effet:
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)

Achèvement de l'index dans Jupyter Notebook
À l'aide de la méthode
_ipython_key_completions_
,
_ipython_key_completions_
pouvez personnaliser l'achèvement de l'index dans un bloc-notes Jupyter. De cette façon, vous pouvez contrôler ce qui est affiché à l'écran si vous appuyez sur Tab après quelque chose comme
d["x
:

Notez que la méthode ne reçoit pas la chaîne à rechercher comme argument.