@Pythonetc junho de 2019


Esta é a décima primeira seleção de dicas e programação em Python no meu feed @pythonetc.

Coleções anteriores


O caractere \ em uma linha regular tem um significado especial. \t é um caractere de tabulação, \r é uma quebra de linha e assim por diante.

Para desabilitar esse comportamento, você pode usar seqüências de caracteres brutas. Então r'\t' se transformará em apenas uma barra invertida t .

Obviamente, você não pode usar ' inside r'...' . E, embora essa restrição possa ser contornada com \ , no entanto, a linha \ ainda permanecerá:

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


Os geradores de lista podem conter mais de um par de expressões if e if :

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

Além disso, qualquer expressão dentro for e if pode usar todas as variáveis ​​definidas anteriormente:

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

Você pode misturar if e for como desejar:

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


A função sorted permite especificar métodos de classificação personalizados. Isso é feito usando o argumento- key , que descreve como converter os valores originais para comparação posterior:

 >>> 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'}] 

Infelizmente, nem todas as bibliotecas que trabalham com comparação suportam o argumento key . Entre os rumores, podem ser mencionados heapq (suporte parcial) e bisect (sem suporte).

Existem duas maneiras de ir nessa situação. Você pode usar objetos personalizados que suportam comparação adequada:

 >>> 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'] 

No entanto, pode ser necessário criar várias versões dessas classes, porque os objetos podem ser comparados de maneiras diferentes. Isso pode ser inconveniente, então existe uma segunda maneira.

Em vez de criar objetos personalizados, você pode usar tuplas (a, b) , nas quais a é o valor a ser comparado (prioridade) b é o valor original:

 >>> 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'] 


A diferença entre a definição e o gerador de funções é a presença da palavra-chave yield no corpo da função:

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

Isso significa que, para criar um gerador vazio, é necessário fazer o seguinte:

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

Mas como o yield from suporta iteradores simples, ou seja, uma versão melhor:

 def g(): yield from [] 


No Python, você pode criar cadeias de operadores de comparação:

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

Tais cadeias não precisam ser matematicamente corretas, você pode misturar > e < :

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

== operadores também são suportados. is e is in :

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

Cada operador se aplica a dois operandos adjacentes. a OP1 b OP2 c estritamente equivalente a (a OP1 b) AND (b OP2 c) . A comparação de a e c não c realizada:

 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) 

Resultado:

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

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


All Articles