@Pythonetc编译2019年3月


这是来自@pythonetc feed的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 

您可以尝试删除所有“无”并在排序后将它们返回(根据任务的不同,返回列表的开头或结尾):

 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 at_fork您可以 os.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' 

要解决此问题,您可以提供一个自定义的起始元素,而不是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_方法, _ipython_key_completions_可以在Jupyter Notebook中自定义索​​引完成。 这样,如果您在d["xd["x之后按Tab,可以控制屏幕上显示的内容。



请注意,该方法不会将要搜索的字符串作为参数接收。

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


All Articles