我的电报频道@pythonetc的提示和技巧,2019年3月

图片

它是我的Telegram频道@pythonetc中有关Python和编程的一些新技巧和窍门。

以前的出版物

0_0


0_0是一个完全有效的Python表达式。

对列表进行无排序


None值对列表进行排序可能是一个挑战:

 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 

您可以尝试删除None,然后将它们排序后放回去(取决于您的任务,到列表的末尾或开头):

 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] 

满嘴 更好的解决方案是使用更复杂的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] 

对于没有无穷大的类型,您可以对元组进行排序:

 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] 

调用random.seed()


当您分叉进程时,您正在使用的随机种子将跨进程复制。 这可能导致进程产生相同的“随机”结果。

为了避免这种情况,您必须在每个进程中手动调用random.seed()

但是,如果您使用的是multiprocessing模块,则不是这种情况,它正为您完成此操作。

这是一个例子:

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

结果是这样的:

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

此外,如果您使用的是Python 3.7或更高版本,由于新的at_fork钩子, os.fork 相同。

上面的Python 3.7代码的输出为:

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

加到0


看起来sum([a, b, c])等价于a + b + c ,而实际上是0 + a + b + c 。 这意味着它不能与不支持加到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' 

要解决此问题,您可以提供自定义的start元素,而不是使用0

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

sum对于floatint类型的求和进行了优化,但是可以处理任何其他自定义类型。 但是,它拒绝对bytesbytearraystr求和,因为join已针对此操作进行了优化:

 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) 



Jupyter Notebook中的索引完成


您可以通过提供_ipython_key_completions_ method在Jupyter笔记本中自定义索​​引完成。 这样,您可以控制在d["x



请注意,该方法不会将查找到的字符串作为参数。

Source: https://habr.com/ru/post/zh-CN447212/


All Articles