Esta é a décima primeira seleção de dicas e programação em Python no meu feed @pythonetc.
←
Coleções anterioresO 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