É uma nova seleção de dicas e truques sobre Python e programação no meu canal Telegram @pythonetc.
Publicações anteriores .
0_0
0_0 é uma expressão Python totalmente válida.
Classificando uma lista com Nenhuma
Classificar uma lista com valores 
None pode ser desafiador:
 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 
Você pode tentar remover o Nones e colocá-los novamente após a classificação (no final ou no início da lista, dependendo da sua tarefa):
 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] 
Isso é um bocado. A melhor solução é usar uma 
key mais complexa:
 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] 
Para tipos em que não há infinito disponível, você pode classificar as tuplas:
 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] 
Chamando random.seed ()
Quando você bifurca seu processo, a semente aleatória que você está usando está copiando entre processos. Isso pode levar a processos que produzem o mesmo resultado "aleatório".
Para evitar isso, você deve chamar manualmente 
random.seed() em todos os processos.
No entanto, esse não é o caso se você estiver usando o módulo de 
multiprocessing , está 
fazendo exatamente isso por você.
Aqui está um exemplo:
 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() 
O resultado é algo como:
 4 4 4 5 5 1 4 1 3 3 2 2 2 2 2 
Além disso, se você estiver usando o Python 3.7 ou mais recente, o 
os.fork fará o mesmo, graças ao novo gancho 
at_fork .
A saída do código acima para Python 3.7 é:
 1 2 2 1 5 4 4 4 5 5 2 4 1 3 1 
Adicionando a 0
Parece que 
sum([a, b, c]) é equivalente a 
a + b + c , enquanto na verdade é 
0 + a + b + c . Isso significa que ele não pode funcionar com tipos que não suportam adicionar a 
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' 
Para corrigir isso, você pode fornecer o elemento inicial personalizado usado em vez de 
0 :
 In : sum([MyInt(1), MyInt(2)], MyInt(0)) Out: MyInt(3) 
sum é bem otimizado para a soma dos tipos 
float e 
int mas pode lidar com qualquer outro tipo personalizado. No entanto, ele se recusa a somar 
bytes , 
bytearray e 
str pois o 
join é bem otimizado para esta operação:
 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) 

Conclusões de índice no notebook jupyter
Você pode personalizar conclusões de índice no bloco de anotações Jupyter, fornecendo o 
_ipython_key_completions_ method . Dessa forma, você pode controlar o que é exibido ao pressionar tab depois de algo como 
d["x :

Observe que o método não obtém a string pesquisada como argumento.