Probar si una variable es una lista o una tupla

8 minutos de lectura

avatar de usuario
interestelar

En Python, ¿cuál es la mejor manera de probar si una variable contiene una lista o una tupla? (es decir, una colección)

Es isinstance() tan malvado como se sugiere aquí? http://www.canonical.org/~kragen/isinstance/

Actualización: la razón más común por la que quiero distinguir una lista de una cadena es cuando tengo un árbol anidado indefinidamente profundo/estructura de datos de listas de listas de listas de cadenas, etc. que estoy explorando con un algoritmo recursivo y necesito para saber cuándo he llegado a los nodos “hoja”.

  • En general, descartar la verificación de tipos como un mal es un poco fácil. Es parte del lenguaje. Si es tan malo, alguien debería escribir un PEP para eliminarlo.

    –Adam Crossland

    2 de febrero de 2010 a las 15:11

  • @Adam Crossland: “Es parte del lenguaje”. Al igual que la división por cero. Es evitable. En este caso, sin información adicional, probablemente sea completamente innecesario. La mayoría de las comprobaciones de tipo en Python son innecesarias. ya que no todos es innecesario, algún tipo de verificación debe estar presente. Pero eso no significa que sea útil, valioso o incluso una buena idea.

    – S. Lott

    2 de febrero de 2010 a las 16:07

  • Entonces, está diciendo que se necesita alguna verificación de tipo, pero a pesar de eso, es inútil, sin valor y una mala idea. Lo siento, eso simplemente no tiene sentido.

    –Glenn Maynard

    2 de febrero de 2010 a las 22:59

  • El “XXX es malvado” es una abreviatura mal concebida y engañosa de “la forma en que pides hacer XXX sugiere que no entiendes cuándo debería usarse realmente, y es casi seguro que quieres algo más”. Es muy probable que ese sea el caso aquí.

    –Glenn Maynard

    2 de febrero de 2010 a las 23:00

  • No lo descarté ampliamente como malvado. Escribí un breve ensayo sobre cuándo es malo y cuándo es justificable. Ese ensayo puede ser muchas cosas: correcto, incorrecto, claro, vago, agradable, aburrido, pero una cosa que no es es un rechazo general de la técnica.

    – Kragen Javier Sitaker

    12 de febrero de 2010 a las 7:55

avatar de usuario
pared-e

if type(x) is list:
    print 'a list'
elif type(x) is tuple:
    print 'a tuple'
else:
    print 'neither a tuple or a list'

  • No parece funcionar: escriba ([]) ==> lista; escribe([]) es lista ===> Falso

    – sten

    5 de junio de 2014 a las 19:56


  • En Python 2.7.5: type([]) is list devoluciones True

    –David Geiger

    6 de junio de 2014 a las 16:38


  • type(x) in [list,tuple] es más corto

    – Alex Holcombe

    15 de enero de 2015 a las 0:28

  • si x y tipo(x) es lista: para evitar el [] discordancia

    –Kenichi Shibata

    26 de junio de 2017 a las 2:32

avatar de usuario
jcdyer

Adelante, usa isinstance si lo necesitas. Es algo malo, ya que excluye secuencias personalizadas, iteradores y otras cosas que realmente podría necesitar. Sin embargo, a veces debe comportarse de manera diferente si alguien, por ejemplo, pasa una cadena. Mi preferencia allí sería verificar explícitamente str o unicode al igual que:

import types
isinstance(var, types.StringTypes)

NB No te equivoques types.StringType por types.StringTypes. Este último incorpora str y unicode objetos.

los types muchos consideran que el módulo está obsoleto a favor de simplemente verificar directamente contra el tipo de objeto, por lo que si prefiere no usar lo anterior, alternativamente puede verificar explícitamente contra str y unicodecomo esto:

isinstance(var, (str, unicode)):

Editar:

Mejor aún es:

isinstance(var, basestring)

Finalizar edición

Después de cualquiera de estos, puede volver a comportarse como si estuviera obteniendo una secuencia normal, permitiendo que las no secuencias generen excepciones apropiadas.

Vea que lo “malo” de la verificación de tipos no es que desee comportarse de manera diferente para un cierto tipo de objeto, es que restringe artificialmente que su función haga lo correcto con tipos de objetos inesperados que de otro modo harían lo correcto. Si tiene un respaldo final que no está verificado, elimina esta restricción. Cabe señalar que demasiada verificación de tipos es un olor de código que indica que es posible que desee realizar una refactorización, pero eso no significa necesariamente que deba evitarlo desde el principio.

  • El módulo de tipos es un poco un artefacto histórico. Como se menciona en docs.python.org/dev/library/types.html#module-types si realmente debe verificar el str type deberías usar eso directamente, en lugar de usar types.StringType que es solo un alias para ello. Pero no creo que esta respuesta responda a la pregunta formulada, porque se trataba de “una colección”. A menos que esté usando un python lo suficientemente nuevo como para tener el abc módulo que no es algo que puedas usar isinstance para verificar, e incluso entonces recomendaría evitar el control si es posible.

    – mzz

    2 de febrero de 2010 a las 16:34

  • assert isinstance(u'abc', str) == False. Estoy de acuerdo en que es mejor verificar el tipo directamente, en lugar de usar el types módulo, pero types.StringTypes hace algo que str no: devuelve True para str y unicode objetos. Editaré mi respuesta para ofrecer una doble verificación como alternativa.

    – jcdyer

    2 de febrero de 2010 a las 18:14

  • Me doy cuenta de que no respondí la pregunta de verificar las colecciones directamente, pero la pregunta real fue “¿Está isinstance mal?” Y di un contraejemplo que (1) es un uso no maligno de isinstanceporque tener un recurso alternativo significa que no se interrumpe la digitación y (2) es una buena solución para una motivación muy común que tienen las personas para querer comprobar si algo es un list o tuple (es decir, para eliminar la ambigüedad de las cadenas).

    – jcdyer

    2 de febrero de 2010 a las 18:18

  • Estoy de acuerdo, con la salvedad de que, a menudo, también es útil que los tipos personalizados se comporten como cadenas. Pero el OO de Python solo llega hasta cierto punto…

    – Kragen Javier Sitaker

    12 de febrero de 2010 a las 7:57

  • Lo hace class Foo(str): pass ¿Haz lo que quieras?

    – jcdyer

    12 de febrero de 2010 a las 15:23

avatar de usuario
scott griffiths

No hay nada de malo en usar isinstance siempre y cuando no sea redundante. Si una variable solo debe ser una lista/tupla, documente la interfaz y utilícela como tal. De lo contrario, un cheque es perfectamente razonable:

if isinstance(a, collections.Iterable):
    # use as a container
else:
    # not a container!

Este tipo de verificación tiene algunos buenos casos de uso, como con la cadena estándar comienza con / termina con métodos (aunque para ser precisos, estos se implementan en C en CPython usando una verificación explícita para ver si es una tupla; hay más de una forma de resolver este problema, como se menciona en el artículo al que se vincula).

Una verificación explícita a menudo es mejor que tratar de usar el objeto como un contenedor y manejar la excepción, lo que puede causar todo tipo de problemas con el código que se ejecuta de forma parcial o innecesaria.

  • Esta es una buena manera de verificar si una variable es iterable. Sin embargo, probablemente no funcionará para los propósitos de esta pregunta. Tenga en cuenta que una cadena también es iterable y probablemente crearía un falso positivo.

    – Corey O.

    24 de julio de 2012 a las 23:16

  • A set El objeto también es iterable, lo que significa que si bien seguramente puede extraer elementos de él, no garantiza un cierto orden, lo cual es algo muy peligroso para ciertos algoritmos. En los casos en que el orden de los elementos importa, un algoritmo que use este fragmento podría generar resultados diferentes en diferentes ejecuciones.

    – ku

    8 de mayo de 2014 a las 12:04

Documente el argumento como si fuera una secuencia y utilícelo como una secuencia. No marque el tipo.

En Python 2.8 type(list) is list devoluciones false

Sugeriría comparar el tipo de esta manera horrible:

if type(a) == type([]) :
  print "variable a is a list"

(bueno, al menos en mi sistema, usando anaconda en Mac OS X Yosemite)

  • ¿Type(a) is list también se evalúa como false?

    – Dmitri Sintsov

    11 de febrero de 2015 a las 11:39

  • ¿Quiso decir Python 2.7.8? python.org/dev/peps/pep-0404/#official-pronouncement

    – Carlos

    9 de agosto de 2017 a las 23:54

  • Hola, tengo curiosidad: ¿Por qué consideras “horrible” tu ejemplo?

    – Seth Connell

    30 de julio de 2018 a las 1:19

  • type(list) is list devoluciones False porque type(list) es typeno list. type(list()) is list o con cualquier otro instancia de una lista volverá True.

    – Michael Greene

    22 de febrero de 2019 a las 21:21

avatar de usuario
Sean Di Zazzo

Qué tal si: hasattr(a, "__iter__") ?

Indica si el objeto devuelto se puede iterar como un generador. De forma predeterminada, las tuplas y las listas pueden hacerlo, pero no los tipos de cadena.

  • ¿Type(a) is list también se evalúa como false?

    – Dmitri Sintsov

    11 de febrero de 2015 a las 11:39

  • ¿Quiso decir Python 2.7.8? python.org/dev/peps/pep-0404/#official-pronouncement

    – Carlos

    9 de agosto de 2017 a las 23:54

  • Hola, tengo curiosidad: ¿Por qué consideras “horrible” tu ejemplo?

    – Seth Connell

    30 de julio de 2018 a las 1:19

  • type(list) is list devoluciones False porque type(list) es typeno list. type(list()) is list o con cualquier otro instancia de una lista volverá True.

    – Michael Greene

    22 de febrero de 2019 a las 21:21

avatar de usuario
tetra5

>>> l = []
>>> l.__class__.__name__ in ('list', 'tuple')
True

¿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