É uma nova seleção de dicas e truques sobre Python e programação no meu canal Telegram @pythonetc.
←
Publicações anterioresO símbolo
\
na sequência regular tem um significado especial.
\t
é caractere de tabulação,
\r
é retorno de carro e assim por diante.
Você pode usar cadeias brutas para desativar esse comportamento.
r'\t'
é apenas barra invertida
t
.
Você obviamente não pode usar
'
inside
r'...'
. No entanto, ele ainda pode ser escapado por
\
, mas
\
é preservado na cadeia de caracteres:
>>> print(r'It\'s insane!') It\'s insane!
As compreensões da lista podem conter mais de uma
for
cláusulas 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 antes:
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
s da maneira que 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 fornecer um método personalizado para classificação. Isso é feito com o argumento-
key
, que descreve como converter valores originais em valores realmente comparados:
>>> 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 algo como esse argumento-
key
. Exemplos notáveis são
heapq
(suporte parcial) e
bisect
(sem suporte).
Existem duas maneiras de lidar com a situação. A primeira é usar objetos personalizados que suportam comparsã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, talvez seja necessário criar várias versões dessas classes, pois há mais de uma maneira de comparar objetos. Pode ser cansativo, mas pode ser facilmente resolvido pela segunda maneira.
Em vez de criar objetos personalizados, você pode usar tuplas
(a, b)
que
a
é o valor a ser comparado (também conhecido como prioirty)
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 definição de função e definição de gerador é 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, você deve fazer algo assim:
In : def g(): ...: if False: ...: yield ...: In : list(g()) Out: []
No entanto, como o
yield from
suporta iteradores simples, essa versão seria melhor:
def g(): yield from []
No Python, você pode encadear operadores de comparação:
>>> 0 < 1 < 2 True >>> 0 < 1 < 0 False
Tais cadeias não precisam ser matematicamente válidas, você pode misturar
>
e
<
:
>>> 0 < 1 > 2 False >>> 0 < 1 < 2 > 1 > 0 True
Outros operadores como
==
,
is
e
in
também são suportados:
>>> [] is not 3 in [1, 2, 3] True
Todo operador é aplicado aos dois operandos mais próximos.
a OP1 b OP2 c
é estritamente igual a
(a OP1 b) AND (b OP2 c)
. Nenhuma comparação entre
a
e
c
está implícita:
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)
Saída:
1 < 2 2 <= 3 3 == 3 True