@Pythonetc compilación marzo de 2019


Esta es la décima colección de consejos y programación de Python de mi feed @pythonetc.

Selecciones anteriores

0_0


0_0 es una expresión completamente correcta en Python.

Ordenar lista con Ninguno


Ordenar una lista con valores None puede ser una tarea desalentadora:

 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 

Puede intentar eliminar todos los Ninguno y devolverlos después de ordenarlos (al principio o al final de la lista, según la tarea):

 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] 

Pero es inconveniente. Mejor use una key más compleja:

 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 estamos hablando de tipos para los que el infinito es inaceptable, puede ordenar las 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] 

Llamar random.seed ()


Cuando bifurcas el proceso, la semilla aleatoria que utilizas se copiará a todos los procesos resultantes. Como resultado, se puede generar el mismo resultado "aleatorio" en ellos.

Para evitar esto, debe llamar manualmente random.seed() en cada proceso. Pero si usa el módulo de multiprocessing , lo hará por usted.

Por ejemplo:

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

Obtén algo como esto:

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

Además, si usa Python 3.7 y superior, entonces gracias al nuevo at_fork at_fork puede hacer lo mismo con os.fork .

El código Python 3.7 anterior da este resultado:

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

Además de 0


A primera vista parece que la sum([a, b, c]) equivalente a a + b + c , aunque en realidad el equivalente sería 0 + a + b + c . Por lo tanto, esta expresión no puede funcionar con tipos que no admiten la adición 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 solucionar esto, puede proporcionar un elemento de inicio personalizado que se utilizará en lugar de 0 :

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

sum diseñado para agregar tipos float e int , aunque puede funcionar con cualquier otro tipo personalizado. Sin embargo, se niega a agregar bytes , bytearray y str , ya que join para este propósito:

 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) 



Finalización del índice en Jupyter Notebook


Usando el método _ipython_key_completions_ , puede personalizar la finalización del índice en un Jupyter Notebook. De esta manera puede controlar lo que se muestra en la pantalla si presiona Tab después de algo como d["x :



Tenga en cuenta que el método no recibe la cadena a buscar como argumento.

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


All Articles