@Pythonetc compilation Março de 2019


Esta é a décima coleção de dicas e programação em Python do meu feed @pythonetc.

Seleções anteriores .

0_0


0_0 é uma expressão completamente correta no Python.

Classificar lista com Nenhum


Classificar uma lista com valores None pode ser uma tarefa assustadora:

 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 excluir todos os Nenhum e retorná-los após a classificação (no início ou no final da lista, dependendo da 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] 

Mas é inconveniente. Melhor 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] 

Se estamos falando de tipos para os quais o infinito é inaceitá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] 

Ligue para random.seed ()


Quando você bifurca o processo, a semente aleatória usada será copiada para todos os processos resultantes. Como resultado, o mesmo resultado "aleatório" pode ser gerado neles.

Para evitar isso, você precisa chamar manualmente random.seed() em cada processo. Mas se você usar o módulo de multiprocessing , ele fará isso por você.

Por 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() 

Obtenha algo parecido com isto:

 4 4 4 5 5 1 4 1 3 3 2 2 2 2 2 

Além disso, se você usa o Python 3.7 e superior, graças ao novo at_fork at_fork, você pode fazer o mesmo com o os.fork .

O código Python 3.7 acima fornece este resultado:

 1 2 2 1 5 4 4 4 5 5 2 4 1 3 1 

Além de 0


À primeira vista, parece que a sum([a, b, c]) equivalente a a + b + c , embora na verdade o equivalente seja 0 + a + b + c . Portanto, essa expressão não pode funcionar com tipos que não suportam adição 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 um elemento inicial personalizado que será usado em vez de 0 :

 In : sum([MyInt(1), MyInt(2)], MyInt(0)) Out: MyInt(3) 

sum projetado para adicionar tipos float e int , embora possa funcionar com outros tipos personalizados. No entanto, ele se recusa a adicionar bytes , bytearray e str , já que join para esse fim:

 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ão do índice no caderno Jupyter


Usando o método _ipython_key_completions_ , _ipython_key_completions_ pode personalizar a conclusão do índice em um Notebook Jupyter. Dessa forma, você pode controlar o que é exibido na tela se pressionar Tab depois de algo como d["x :



Observe que o método não recebe a sequência a ser pesquisada como argumento.

Source: https://habr.com/ru/post/pt447210/


All Articles