Estou tentando entender como as funções internas any()
e all()
Python funcionam.
Estou tentando comparar as tuplas para que, se algum valor for diferente, ele retorne True
e, se forem todos iguais, retorne False
. Como eles estão trabalhando neste caso para retornar [Falso, Falso, Falso]?
d
é um defaultdict(list)
.
print d['Drd2']
# [[1, 5, 0], [1, 6, 0]]
print list(zip(*d['Drd2']))
# [(1, 1), (5, 6), (0, 0)]
print [any(x) and not all(x) for x in zip(*d['Drd2'])]
# [False, False, False]
Que eu saiba, isso deve gerar
# [False, True, False]
já que (1,1) são iguais, (5,6) são diferentes e (0,0) são iguais.
Por que está avaliando para Falso para todas as tuplas?
Respostas:
Você pode pensar aproximadamente
any
eall
como uma série de operadores lógicosor
eand
, respectivamente.qualquer
any
retornaráTrue
quando pelo menos um dos elementos for Truthy. Leia sobre o Teste do valor da verdade.tudo
all
retornaráTrue
apenas quando todos os elementos forem Truthy.Tabela da verdade
Nota 1: O caso iterável vazio é explicado na documentação oficial, como esta
any
Como nenhum dos elementos é verdadeiro, ele retorna
False
neste caso.all
Como nenhum dos elementos é falso, ele retorna
True
neste caso.Nota 2:
Outra coisa importante a saber
any
eall
é que ela irá causar um curto-circuito na execução, no momento em que souberem o resultado. A vantagem é que todo iterável não precisa ser consumido. Por exemplo,Aqui
(not (i % 6) for i in range(1, 10))
está uma expressão geradora que retornaTrue
se o número atual entre 1 e 9 for um múltiplo de 6.any
itera omultiples_of_6
e, quando ele se encontra6
, encontra um valor Truthy, então retorna imediatamenteTrue
e o restantemultiples_of_6
não é iterado. Isso é o que vemos quando imprimirlist(multiples_of_6)
, o resultado de7
,8
e9
.Essa coisa excelente é usada de maneira muito inteligente nesta resposta .
Com este entendimento básico, se olharmos para o seu código, você faz
o que garante que, pelo menos um dos valores seja Truthy, mas não todos. É por isso que está voltando
[False, False, False]
. Se você realmente quis verificar se os dois números não são iguais,fonte
bool(data) and all(...)
deve funcionar.any
eall
pegue iterables e retorneTrue
se houver algum ou todos (respectivamente) dos elementosTrue
.Se os iterables estiverem vazios,
any
retornaráFalse
eall
retornaráTrue
.Eu estava demonstrando
all
eany
para os alunos nas aulas hoje. Eles estavam principalmente confusos sobre os valores de retorno para iterables vazios. Explicá-lo dessa maneira fez com que muitas lâmpadas acendessem.Comportamento de atalho
Eles,
any
eall
, tanto olhar para uma condição que lhes permite parar de avaliar. Os primeiros exemplos que eu dei exigiram que eles avaliassem o booleano de cada elemento da lista inteira.(Observe que o literal da lista não é avaliado preguiçosamente - você pode obtê-lo com um iterador - mas isso é apenas para fins ilustrativos.)
Aqui está uma implementação Python de todo e qualquer:
Obviamente, as implementações reais são escritas em C e têm muito mais desempenho, mas você pode substituir as opções acima e obter os mesmos resultados para o código nesta (ou em qualquer outra) resposta.
all
all
verifica a existência de elementosFalse
(para que ele possa retornarFalse
) e, em seguida, retornaTrue
se nenhum deles foiFalse
.any
A maneira como
any
funciona é que ele verifica se há elementosTrue
(para que possa retornarTrue), then it returns
Falseif none of them were
True`.Penso que, se você se lembrar do comportamento de atalho, entenderá intuitivamente como eles funcionam sem precisar fazer referência a uma Tabela da Verdade.
Evidência de
all
eany
atalho:Primeiro, crie um noisy_iterator:
e agora vamos iterar ruidosamente nas listas, usando nossos exemplos:
Nós podemos ver
all
paradas na primeira verificação booleana falsa.E
any
para na primeira verificação booleana True:A fonte
Vamos olhar a fonte para confirmar o acima.
Aqui está a fonte para
any
:E aqui está a fonte para
all
:fonte
Python/bltinmodule.c
- eu adicionei ao acima.Eu sei que isso é antigo, mas achei que seria útil mostrar como essas funções se parecem no código. Isso realmente ilustra a lógica, melhor que o texto ou uma tabela IMO. Na realidade, eles são implementados em C, e não em Python puro, mas são equivalentes.
Em particular, você pode ver que o resultado para iterables vazios é apenas o resultado natural, não um caso especial. Você também pode ver o comportamento em curto-circuito; seria realmente mais trabalho para não haver curto-circuito.
Quando Guido van Rossum (o criador do Python) propôs a adição
any()
eall()
ele os explicou postando exatamente os trechos de código acima.fonte
O código em questão que você está perguntando vem da minha resposta dada aqui . O objetivo era resolver o problema de comparar várias matrizes de bits - ou seja, coleções de
1
e0
.any
eall
são úteis quando você pode confiar na "veracidade" dos valores - ou seja, seu valor em um contexto booleano. 1 éTrue
e 0 éFalse
, uma conveniência que essa resposta alavancou. 5 passa a ser tambémTrue
, então quando você mistura isso em suas possíveis entradas ... bem. Não funcionaVocê poderia fazer algo assim:
Falta a estética da resposta anterior (eu realmente gostei da aparência
any(x) and not all(x)
), mas faz o trabalho.fonte
True
quando os valores são diferentes, o comprimento do conjunto deve ser 2, e não 1.fonte
fonte
O conceito é simples:
fonte
fonte