@Pythonetc 2019年6月


这是我的@pythonetc feed中的Python技巧和编程的第11种选择。

以前的收藏


常规行上的\字符具有特殊含义。 \t是制表符, \r是换行符,依此类推。

若要禁用此行为,可以使用原始字符串。 然后r'\t'将变成反斜杠和t

显然,您不能使用' inside r'...' 。 并且尽管可以使用\来绕过此限制,但是\行仍将保留:

 >>> print(r'It\'s insane!') It\'s insane! 


列表生成器可以包含一对以上的forif表达式:

 In : [(x, y) for x in range(3) for y in range(3)] Out: [ (0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2) ] In : [ (x, y) for x in range(3) for y in range(3) if x != 0 if y != 0 ] Out: [(1, 1), (1, 2), (2, 1), (2, 2)] 

另外, forif内部的任何表达式都可以使用所有先前定义的变量:

 In : [ (x, y) for x in range(3) for y in range(x + 2) if x != y ] Out: [ (0, 1), (1, 0), (1, 2), (2, 0), (2, 1), (2, 3) ] 

您可以根据需要随意混合:

 In : [ (x, y) for x in range(5) if x % 2 for y in range(x + 2) if x != y ] Out: [ (1, 0), (1, 2), (3, 0), (3, 1), (3, 2), (3, 4) ] 


sorted功能允许sorted指定自定义排序方法。 这是使用key参数完成的,该参数描述了如何转换原始值以供以后比较:

 >>> x = [dict(name='Vadim', age=29), dict(name='Alex', age=4)] >>> sorted(x, key=lambda v: v['age']) [{'age': 4, 'name': 'Alex'}, {'age': 29, 'name': 'Vadim'}] 

las,不是所有使用比较的库都支持key参数。 在那些谣言中,可以提到heapq (部分支持)和bisect (不支持)。

在这种情况下有两种方法。 您可以使用支持适当比较的自定义对象:

 >>> class User: ... def __init__(self, name, age): ... self.name = name ... self.age = age ... def __lt__(self, other): ... return self.age < other.age ... >>> x = [User('Vadim', 29), User('Alex', 4)] >>> [x.name for x in sorted(x)] ['Alex', 'Vadim'] 

但是,您可能需要创建此类的多个版本,因为可以用不同的方式比较对象。 这可能会带来不便,因此还有第二种方法。

除了创建自定义对象外,还可以使用元组(a, b) ,其中a是要比较的值(优先级), b是原始值:

 >>> users = [dict(name='Vadim', age=29), dict(name='Alex', age=4)] >>> to_sort = [(u['age'], u) for u in users] >>> [x[1]['name'] for x in sorted(to_sort)] ['Alex', 'Vadim'] 


定义和函数生成器之间的区别是函数主体中存在yield关键字:

 In : def f(): ...: pass ...: In : def g(): ...: yield ...: In : type(f()) Out: NoneType In : type(g()) Out: generator 

这意味着要创建一个空的生成器,您需要执行以下操作:

 In : def g(): ...: if False: ...: yield ...: In : list(g()) Out: [] 

但是由于yield from支持简单的迭代器,即更好的版本:

 def g(): yield from [] 


在Python中,您可以创建比较运算符链:

 >>> 0 < 1 < 2 True >>> 0 < 1 < 0 False 

这样的链不必在数学上正确,您可以将><混合使用:

 >>> 0 < 1 > 2 False >>> 0 < 1 < 2 > 1 > 0 True 

还支持==运算符。 isin

 >>> [] is not 3 in [1, 2, 3] True 

每个运算符适用于两个相邻的操作数。 a OP1 b OP2 c严格等于(a OP1 b) AND (b OP2 c) 。 不执行ac比较:

 class Spy: def __init__(self, x): self.x = x def __eq__(self, other): print(f'{self.x} == {other.x}') return self.x == other.x def __ne__(self, other): print(f'{self.x} != {other.x}') return self.x != other.x def __lt__(self, other): print(f'{self.x} < {other.x}') return self.x < other.x def __le__(self, other): print(f'{self.x} <= {other.x}') return self.x <= other.x def __gt__(self, other): print(f'{self.x} > {other.x}') return self.x > other.x def __ge__(self, other): print(f'{self.x} >= {other.x}') return self.x >= other.x s1 = Spy(1) s2 = Spy(2) s3 = Spy(3) print(s1 is s1 < s2 <= s3 == s3) 

结果:

 1 < 2 2 <= 3 3 == 3 True 

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


All Articles