¿Cómo verificar si una variable es un diccionario en Python?

9 minutos de lectura

avatar de usuario
Riley

¿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)

  • 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

avatar de usuario
padraic cunningham

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)

  • Voté negativamente esta respuesta porque la respuesta correcta a la pregunta general es: isinstance(ele, collections.Mapping). funciona para dict(), collections.OrderedDict()y collections.UserDict(). El ejemplo en la pregunta es lo suficientemente específico para que la respuesta de Padriac funcione, pero no es lo suficientemente bueno para el caso general.

    – Alejandro Ryzhov

    28 de junio de 2018 a las 5:31

  • Rechacé esta respuesta porque si vas a invocar ele.items() ¿Por qué estás revisando el tipo? EAFP/duck-typing funciona aquí, simplemente envuelva for k,v in ele.items() en try...except (AttributeError, TypeError). Si se levanta una excepción, ya sabes ele no tiene items que produce un iterable…

    – cowbert

    14 de julio de 2018 a las 3:31


  • @Padraic Cunningham Su caso hipotético requeriría que su clase personalizada “100% no es un dictado” 1. tuviera un items() método 2. que dio la casualidad de producir un iterable y 3. donde cada elemento de ese iterable se puede representar como una tupla de 2. En este punto, su objeto personalizado ya ha implementado la mitad de un dictado. A los efectos del código enumerado, solo nos preocupamos por la expansión condicional del elemento anidado, y su objeto personalizado ya lo implementa. (Es un poco irónico que critiques el comentario de @Alexander Ryzhov por ser demasiado general, pero ahora planteas un caso general)

    – cowbert

    14 de julio de 2018 a las 16:17

  • @PadraicCunningham, para empezar, preferiría no enseñar a las personas que no están demasiado familiarizadas con los antipatrones de Python. Hay muy pocos casos de uso en Python que requerir Comprobación de tipo explícita: la mayoría proviene de heredar una mala implementación para empezar (‘objeto de Dios, anulando construcciones estándar de biblioteca/lenguaje, etc.) La pregunta original es en sí misma un problema XY. ¿Por qué el OP necesita verificar el tipo? Porque según su código lo que realmente quieren hacer es comprobar si un elemento de su colección se comporta como una colección (implementos items() que produce un iterable anidado).

    – cowbert

    14/07/2018 a las 21:02

  • @AlexanderRyzhov ¿Por qué no publicar ese enfoque como respuesta? Por cierto, como Josh Kelley ha comentado anteriormente sugiriendo collections.abc.Mappinguna nota podría ser apropiada de que son iguales, pero collections.abc no está disponible antes de Python 3.3. collections.Mapping alias todavía está disponible en Python 3.6, pero no está documentado, por lo que probablemente uno debería preferir collections.abc.Maping.

    – Yushin Washio

    26 de febrero de 2019 a las 12:27

¿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, defaultdicto 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 dicty 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 isinstanceconsidere abstracciones como Mapping o MutableMappingy considere evitar la verificación de tipos por completo, usando la interfaz directamente.

  • Explicación bien escrita de las opciones y cuándo/por qué elegirlas.

    – Jesse Chisholm

    16 sep 2020 a las 19:47

  • Creo que es demasiado rápido llegar a la conclusión de que “No usar es verificar los tipos para el flujo de control estándar”. Necesitamos evaluar los conceptos básicos caso por caso. En algunos casos, es más deseable tener un control de verificación estricto, donde desea asegurarse de que sea del tipo 1 y solo 1, pero sin incluir a sus hijos.

    –Cheok Yan Cheng

    14 abr 2021 a las 10:31

  • En este punto, con la verificación de tipo estático de mypy y match saliendo con casos que admiten la herencia, esta respuesta debe actualizarse un poco con un poco más de matices.

    – Rusia debe sacar a Putin

    14/04/2021 a las 13:50

avatar de usuario
David

En pitón 3.6

    typeVariable = type(variable)
    
    print('comparison',typeVariable == dict)

    if typeVariable == dict:
        #'true'
    else:
        #'false'

avatar de usuario
Leva

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í

avatar de usuario
CodeMantle

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)

  • dict.iteritems() no existe en Python 3, debe usar dict.items() en cambio.

    – Arkelis

    6 mayo 2020 a las 14:31

  • @Arkelis Ups, acabo de copiar/pegar esa parte, gracias por señalarlo, corregido ahora.

    – CodeMantle

    7 de mayo de 2020 a las 8:22

  • Un comentario sobre los cosméticos — En mi opinión, la reutilización de k,v en bucles anidados se ve funky. También significa que el interior print(k,v) no representa el exterior k en la lista mostrada.

    – Jesse Chisholm

    16 sep 2020 a las 19:50


  • @JesseChisholm, tiene toda la razón, ¡necesita ajuste (listo)!

    – CodeMantle

    16 de septiembre de 2020 a las 23:24

  • ¿Cómo es diferente de typing.Mapping?

    – tejasvi88

    6 de julio de 2021 a las 5:15

  • dict.iteritems() no existe en Python 3, debe usar dict.items() en cambio.

    – Arkelis

    6 mayo 2020 a las 14:31

  • @Arkelis Ups, acabo de copiar/pegar esa parte, gracias por señalarlo, corregido ahora.

    – CodeMantle

    7 de mayo de 2020 a las 8:22

  • Un comentario sobre los cosméticos — En mi opinión, la reutilización de k,v en bucles anidados se ve funky. También significa que el interior print(k,v) no representa el exterior k en la lista mostrada.

    – Jesse Chisholm

    16 sep 2020 a las 19:50


  • @JesseChisholm, tiene toda la razón, ¡necesita ajuste (listo)!

    – CodeMantle

    16 de septiembre de 2020 a las 23:24

  • ¿Cómo es diferente de typing.Mapping?

    – tejasvi88

    6 de julio de 2021 a las 5:15

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad