Probar si una variable es una lista o tupla
En Python, ¿cuál es la mejor manera de comprobar 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 algún árbol/estructura de datos anidado indefinidamente profundo 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".
if type(x) is list:
print 'a list'
elif type(x) is tuple:
print 'a tuple'
else:
print 'neither a tuple or a list'
Continúe y úselo isinstance
si lo necesita. Es algo malo, ya que excluye secuencias personalizadas, iteradores y otras cosas que realmente puedas necesitar. Sin embargo, a veces es necesario comportarse de manera diferente si alguien, por ejemplo, pasa una cadena. Mi preferencia sería verificar explícitamente str
o unicode
me gusta así:
import types
isinstance(var, types.StringTypes)
NB No lo confunda types.StringType
con types.StringTypes
. Este último incorpora str
y unicode
objetos.
Muchos consideran que el types
módulo está obsoleto y prefieren simplemente verificarlo directamente con el tipo de objeto, por lo que si prefiere no usar lo anterior, también puede verificar explícitamente con str
y unicode
, de esta manera:
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 las excepciones apropiadas.
Mira, lo "malo" de la verificación de tipos no es que quieras comportarte de manera diferente para un determinado tipo de objeto, sino que restringes artificialmente que tu función haga lo correcto con tipos de objetos inesperados que de otro modo harían lo correcto. Si tiene una reserva final que no tiene verificación de tipo, elimina esta restricción. Cabe señalar que demasiada verificación de tipos es un olor a código que indica que es posible que desee realizar alguna refactorización, pero eso no significa necesariamente que deba evitarlo desde el principio.
No hay nada de malo en usarlo isinstance
siempre que 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.abc.Iterable):
# use as a container
else:
# not a container!
Este tipo de verificación tiene algunos buenos casos de uso, como con los métodos estándar de cadena comienza con / termina con (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). para resolver este problema, como se menciona en el artículo al que enlaza).
Una verificación explícita suele ser mejor que intentar usar el objeto como contenedor y manejar la excepción, lo que puede causar todo tipo de problemas con el código que se ejecuta parcial o innecesariamente.
Documente el argumento como si fuera una secuencia y utilícelo como una secuencia. No marque el tipo.
type(list) is list
En los retornos de Python 2.8, false
sugeriría comparar el tipo de esta horrible manera:
if type(a) == type([]) :
print "variable a is a list"
(bueno, al menos en mi sistema, usando anaconda en Mac OS X Yosemite)