¿Cómo verificaría si una variable es un diccionario en Python?
Por ejemplo, me gustaría que recorra los valores en el diccionario hasta que encuentre un diccionario. Luego, recorre el que encuentra:
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)
podrías usar if type(ele) is dict
o usar isinstance(ele, dict)
que funcionaría si hubiera subclasificado dict
:
d = {'abc': 'abc', 'def': {'ghi': 'ghi', 'jkl': 'jkl'}}
for element in d.values():
if isinstance(element, dict):
for k, v in element.items():
print(k,' ',v)
¿Cómo verificaría si una variable es un diccionario en Python?
Esta es una excelente pregunta, pero es desafortunado que la respuesta más votada conduzca a una mala recomendación. type(obj) is dict
.
(Tenga en cuenta que tampoco debe usar dict
como nombre de variable – es el nombre del objeto integrado.)
Si está escribiendo código que será importado y utilizado por otros, no asuma que usarán el dictado incorporado directamente; hacer esa presunción hace que su código sea más inflexible y, en este caso, cree errores fácilmente ocultos que no provocarían errores en el programa. .
Sugiero enfáticamente, con el propósito de corrección, mantenibilidad y flexibilidad para los usuarios futuros, nunca tener expresiones unidiomáticas menos flexibles en su código cuando hay expresiones idiomáticas más flexibles.
is
es una prueba para identidad del objeto. No admite la herencia, no admite ninguna abstracción y no admite la interfaz.
Así que voy a proporcionar varias opciones que lo hacen.
Herencia de apoyo:
Esta es la primera recomendación que haría, porque permite a los usuarios proporcionar su propia subclase de dict, o una OrderedDict
, defaultdict
o Counter
desde el módulo de colecciones:
if isinstance(any_object, dict):
Pero hay opciones aún más flexibles.
Abstracciones de apoyo:
from collections.abc import Mapping
if isinstance(any_object, Mapping):
Esto le permite al usuario de su código usar su propia implementación personalizada de un Mapeo abstracto, que también incluye cualquier subclase de dict
y aún obtener el comportamiento correcto.
Usa la interfaz
Comúnmente escucha el consejo de programación orientada a objetos, “programa a una interfaz”.
Esta estrategia aprovecha el polimorfismo de Python o la tipificación pato.
Así que simplemente intente acceder a la interfaz, capturando los errores esperados específicos (AttributeError
en caso de que no haya .items
y TypeError
en caso items
no se puede llamar) con un respaldo razonable, y ahora cualquier clase que implemente esa interfaz le dará sus elementos (nota .iteritems()
se ha ido en Python 3):
try:
items = any_object.items()
except (AttributeError, TypeError):
non_items_behavior(any_object)
else: # no exception raised
for item in items: ...
Tal vez podría pensar que usar el tipo de pato como este va demasiado lejos al permitir demasiados falsos positivos, y puede ser, dependiendo de sus objetivos para este código.
Conclusión
no usar is
para comprobar los tipos de flujo de control estándar. Usar isinstance
considere abstracciones como Mapping
o MutableMapping
y considere evitar la verificación de tipos por completo, usando la interfaz directamente.
En pitón 3.6
typeVariable = type(variable)
print('comparison',typeVariable == dict)
if typeVariable == dict:
#'true'
else:
#'false'
Mis pruebas han encontrado que esto funciona ahora que tenemos sugerencias de tipo:
from typing import Dict
if isinstance(my_dict, Dict):
# True
else:
# False
Nota al margen sobre una discusión sobre escribir. Dictar aquí
El OP no excluyó la variable de inicio, por lo que para completar, aquí se explica cómo manejar el caso genérico de procesar un supuesto diccionario que puede incluir elementos como diccionarios.
También siguiendo el Python puro (3.8) forma recomendada para probar el diccionario en los comentarios anteriores.
from collections.abc import Mapping
my_dict = {'abc': 'abc', 'def': {'ghi': 'ghi', 'jkl': 'jkl'}}
def parse_dict(in_dict):
if isinstance(in_dict, Mapping):
for k_outer, v_outer in in_dict.items():
if isinstance(v_outer, Mapping):
for k_inner, v_inner in v_outer.items():
print(k_inner, v_inner)
else:
print(k_outer, v_outer)
parse_dict(my_dict)
También stackoverflow.com/questions/378927/… (que está marcado como un duplicado del anterior).
– ENP
10 de agosto de 2014 a las 19:03
También stackoverflow.com/q/2225038/770830
– se real
10/08/2014 a las 19:05
No, no es la misma pregunta. La respuesta a esta pregunta y a las otras preguntas enumeradas aquí contienen sustancialmente la misma información. Pero la respuesta a “Cómo comprobar si una variable es un diccionario en python” es “Usar type() o isinstance()”, lo que lleva a una nueva pregunta, cuál es la diferencia entre type() e isinstance() . Pero la persona que hace la primera pregunta no puede saberlo hasta que se responda la primera pregunta. Ergo, diferentes preguntas, lo que importa cuando busca su pregunta en el sitio.
– usuario2177304
06/01/2016 a las 22:44
Estoy de acuerdo con @mbakeranalecta. Vine aquí buscando la respuesta a la pregunta “¿Cómo verificar si una variable es un diccionario en Python?” y nunca hubiera pensado en buscar mi respuesta en “Diferencias entre isinstance() y type() en python”.
– lodebari
14 de enero de 2016 a las 14:46
Para verificar si una variable es un diccionario en particular, probablemente debería usar
isinstance(v, collections.abc.Mapping)
. En otras palabras, este no es un duplicado exacto de “Diferencias entre isinstance() y type()”.–Josh Kelley
1 mayo 2017 a las 20:08