Como você verificaria se uma variável é um dicionário em python?
Por exemplo, eu gostaria que ele repetisse os valores no dicionário até encontrar um dicionário. Em seguida, faça um loop pelo que encontrar:
dict = {'abc': 'abc', 'def': {'ghi': 'ghi', 'jkl': 'jkl'}}
for k, v in dict.iteritems():
if ###check if v is a dictionary:
for k, v in v.iteritems():
print(k, ' ', v)
else:
print(k, ' ', v)
python
dictionary
Riley
fonte
fonte
isinstance(v, collections.abc.Mapping)
. Em outras palavras, essa não é uma duplicata exata de "Diferenças entre isinstance () e type ()".Respostas:
Você poderia usar
if type(ele) is dict
ou usar oisinstance(ele, dict)
que funcionaria se você tivesse subclassificadodict
:fonte
isinstance(ele, collections.Mapping)
. Ele trabalha paradict()
,collections.OrderedDict()
ecollections.UserDict()
. O exemplo da pergunta é específico o suficiente para a resposta de Padriac funcionar, mas não é bom o suficiente para o caso geral.ele.items()
por que está verificando o tipo? O EAFP / digitação de pato funciona aqui, apenas envolvafor k,v in ele.items()
-otry...except (AttributeError, TypeError)
. Se exceção é gerada, você sabeele
não temitems
que produz um iterable ...items()
método 2. que por acaso produzia um iterável e 3. onde cada elemento desse iterável pode ser representado como um 2 -tuplo. Neste ponto, seu objeto personalizado já implementou metade de um ditado. Para os fins do código listado, apenas nos preocupamos com a expansão condicional do elemento aninhado, e seu objeto personalizado já o implementa. (É um pouco irônico que você critica o comentário de @Alexander Ryzhov por ser muito geral, mas agora levantar um caso geral)items()
que produzem uma iterável aninhada).collections.abc.Mapping
, uma nota pode ser apropriado que eles são o mesmo, mascollections.abc
não está disponível antes de Python 3.3.collections.Mapping
O alias ainda está disponível no Python 3.6, mas não está documentado, portanto, provavelmente, deve-se preferircollections.abc.Maping
.Essa é uma excelente pergunta, mas é lamentável que a resposta mais votada leve a uma recomendação ruim
type(obj) is dict
.(Observe que você também não deve usar
dict
como um nome de variável - é o nome do objeto interno.)Se você estiver escrevendo um código que será importado e usado por outras pessoas, não presuma que eles usarão o dict diretamente - tornando essa suposição mais flexível e, nesse caso, crie bugs facilmente ocultos que não prejudicariam o programa. .
Eu sugiro fortemente, para fins de correção, manutenção e flexibilidade para usuários futuros, nunca ter expressões unidiomatic menos flexíveis em seu código quando houver expressões idiomáticas mais flexíveis.
is
é um teste para a identidade do objeto . Não suporta herança, não suporta abstração e não suporta a interface.Então, vou fornecer várias opções que o fazem.
Herança de suporte:
Esta é a primeira recomendação gostaria de fazer, porque permite que os usuários forneçam seus próprios subclasse de dict, ou uma
OrderedDict
,defaultdict
ouCounter
das coleções módulo:if isinstance(any_object, dict):
Mas existem opções ainda mais flexíveis.
Abstrações de suporte:
Isso permite que o usuário do seu código use sua própria implementação personalizada de um mapeamento abstrato, que também inclui qualquer subclasse de
dict
, e ainda obtenha o comportamento correto.Use a interface
Você geralmente ouve os conselhos do OOP, "programa para uma interface".
Essa estratégia aproveita o polimorfismo do Python ou a digitação de patos.
Então, basta tentar acessar a interface, pegando os erros específicos esperado (
AttributeError
no caso, não há.items
eTypeError
no casoitems
não é resgatável) com um fallback razoável - e agora qualquer classe que implementa essa interface vai lhe dar os seus itens (nota.iteritems()
é ido em Python 3):Talvez você pense que usar a digitação de pato dessa maneira vá longe demais ao permitir muitos falsos positivos, e pode ser, dependendo dos seus objetivos para este código.
Conclusão
Não use
is
para verificar os tipos quanto ao fluxo de controle padrão. Useisinstance
, considere abstrações comoMapping
ouMutableMapping
e evite a verificação de tipo completamente, usando a interface diretamente.fonte
O OP não excluiu a variável inicial, portanto, para completar, veja como lidar com o caso genérico de processar um suposto dicionário que pode incluir itens como dicionários.
Também seguindo a maneira recomendada pura de Python (3.8) para testar o dicionário nos comentários acima.
fonte
dict.iteritems()
não existe no Python 3, você deve usardict.items()
.