Eu sei como usar os loops e as instruções if em linhas separadas, como:
>>> a = [2,3,4,5,6,7,8,9,0]
... xyz = [0,12,4,6,242,7,9]
... for x in xyz:
... if x in a:
... print(x)
0,4,6,7,9
E sei que posso usar uma compreensão de lista para combiná-las quando as declarações são simples, como:
print([x for x in xyz if x in a])
Mas o que não consigo encontrar é um bom exemplo em qualquer lugar (para copiar e aprender), demonstrando um conjunto complexo de comandos (não apenas "print x") que ocorrem após a combinação de um loop for e algumas declarações if. Algo que eu esperaria se parecer com:
for x in xyz if x not in a:
print(x...)
Não é assim que o python deve funcionar?
python
loops
if-statement
for-loop
ChewyChunks
fonte
fonte
for
loop eif
declaração explícitos .x in a
é lento sea
houver uma lista.Respostas:
Você pode usar expressões geradoras como esta:
fonte
gen = (y for (x,y) in enumerate(xyz) if x not in a)
retorna >>>12
quando digitofor x in gen: print x
- então por que o comportamento inesperado com enumerar?for x in xyz if x:
for x in (x for x in xyz if x not in a):
trabalha para mim, mas por que você não deve apenas ser capaz de fazerfor x in xyz if x not in a:
, eu não tenho certeza ...Conforme The Zen of Python (se você está se perguntando se o seu código é "Pythonic", esse é o lugar certo):
A maneira pitônica de obter o valor de dois s é:
sorted
intersection
set
Ou os elementos que estão
xyz
mas não estão ema
:Mas para um loop mais complicado, você pode planificá-lo iterando sobre uma expressão de gerador bem nomeada e / ou chamando para uma função bem nomeada. Tentar encaixar tudo em uma linha raramente é "pitonico".
Atualize após comentários adicionais sobre sua pergunta e a resposta aceita
Não sei ao certo o que você está tentando fazer
enumerate
, mas sea
for um dicionário, você provavelmente desejará usar as teclas, assim:fonte
Pessoalmente, acho que esta é a versão mais bonita:
Editar
Se você deseja evitar o uso do lambda, pode usar o aplicativo de funções parciais e usar o módulo do operador (que fornece funções para a maioria dos operadores).
https://docs.python.org/2/library/operator.html#module-operator
fonte
filter(a.__contains__, xyz)
. Geralmente, quando as pessoas usam lambda, elas realmente precisam de algo muito mais simples.__contains__
é um método como outro qualquer, apenas é um método especial , o que significa que pode ser chamado indiretamente por um operador (in
neste caso). Mas também pode ser chamado diretamente, faz parte da API pública. Os nomes privados são definidos especificamente como tendo no máximo um sublinhado à direita, para fornecer exceção a nomes de métodos especiais - e estão sujeitos a nomes incorretos quando lexicamente nos escopos de classe. Consulte docs.python.org/3/reference/datamodel.html#specialnames e docs.python.org/3.6/tutorial/classes.html#private-variables .in
é despachado individualmente pelo operando certo). Além disso, observe queoperator
também exportacontains
método sob o nome__contains__
, portanto, certamente não é um nome privado. Acho que você precisará aprender a conviver com o fato de que nem todo sublinhado duplo significa "afastar-se". : -]lambda
necessidades de fixação para incluirnot
:lambda w: not w in a, xyz
A seguir, é uma simplificação / uma linha da resposta aceita:
Observe que o
generator
foi mantido em linha . Isso foi testadopython2.7
epython3.6
(observe os parênteses noprint
;))fonte
Eu provavelmente usaria:
fonte
pythonic
Eu posso codificar funcionalmente em qualquer outro idioma que eu uso (scala, kotlin, javascript, R, swift, ..) mas difícil / estranho em pythonfonte
import time a = [2,3,4,5,6,7,8,9,0] xyz = [0,12,4,6,242,7,9] start = time.time() print (set(a) & set(xyz)) print time.time() - start
if x in ignore: ...
.if set(a) - set(ignore) == set([]):
então talvez seja por isso que foi muito mais lento do que verificar a adesão Vou testar isso novamente no futuro em um exemplo muito mais simples do que o que eu estou escrevendo..Você também pode usar geradores , se as expressões do gerador ficarem muito envolvidas ou complexas:
fonte
Use
intersection
ouintersection_update
interseção :
intersection_update :
então
b
é sua respostafonte
Gostei da resposta de Alex , porque um filtro é exatamente um se aplicado a uma lista. Portanto, se você deseja explorar um subconjunto de uma lista com uma condição, essa parece ser a maneira mais natural
esse método é útil para a separação de preocupações, se a função de condição for alterada, o único código a ser utilizado é a própria função
O método gerador parece melhor quando você não deseja membros da lista, mas uma modificação desses membros, que parece mais adequada a um gerador
Além disso, os filtros funcionam com geradores, embora neste caso não seja eficiente
Mas é claro, ainda seria bom escrever assim:
fonte
Uma maneira simples de encontrar elementos comuns exclusivos das listas aeb:
fonte