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 / estructura de datos de listas de listas de listas de cadenas, etc., que estoy explorando con un algoritmo recursivo y necesito saber cuándo he golpeado los nodos "hoja".
Respuestas:
Siga adelante y utilícelo
isinstance
si lo necesita. Es algo malvado, ya que excluye secuencias personalizadas, iteradores y otras cosas que realmente pueda necesitar. Sin embargo, a veces debe comportarse de manera diferente si alguien, por ejemplo, pasa una cadena. Mi preferencia sería verificar explícitamentestr
o de estaunicode
manera:NB No te confundas
types.StringType
contypes.StringTypes
. Este último incorporastr
yunicode
objetos.El
types
módulo es considerado por muchos como obsoleta en favor de sólo la comprobación directamente contra el tipo del objeto, así que si usted prefiere no utilizar el anterior, alternativamente, puede comprobar de forma explícita en contrastr
yunicode
, de esta manera:Editar:
Mejor aún es:
Finalizar edición
Después de cualquiera de estos, puede volver a comportarse como si estuviera obteniendo una secuencia normal, dejando que las no secuencias generen las excepciones apropiadas.
Vea que lo "malo" de la verificación de tipos no es que desee comportarse de manera diferente para un determinado tipo de objeto, es que restringe artificialmente su función de hacer lo correcto con tipos de objetos inesperados que de otro modo harían lo correcto. Si tiene una copia de seguridad final que no está marcada, elimine esta restricción. Cabe señalar que demasiada verificación de tipo es un olor a código que indica que es posible que desee refactorizar, pero eso no significa necesariamente que deba evitarlo desde el principio.
fuente
str
tipo, simplemente debe usarlo directamente, en lugar de usar,types.StringType
que es solo un alias para él. Pero no creo que esta respuesta responda a la pregunta formulada, porque se trataba de "una colección". A menos que esté utilizando una python lo suficientemente nueva como para tener elabc
módulo que no es algo que pueda usarisinstance
para verificar, e incluso entonces recomendaría evitar la verificación si es posible.assert isinstance(u'abc', str) == False
. Estoy de acuerdo en que es mejor verificar el tipo directamente, en lugar de usar eltypes
módulo, perotypes.StringTypes
hace algo questr
no: devuelve True parastr
yunicode
objetos. Editaré mi respuesta para ofrecer una doble verificación como alternativa.isinstance
malo?" Y di un contraejemplo en el que (1) es un uso no malvadoisinstance
, porque tener un retroceso significa que no rompe el patito, y (2) es una buena solución para una motivación muy común que las personas tienen para querer verificar si algo es unlist
otuple
(es decir, desambiguarlos de las cadenas).class Foo(str): pass
lo que quieres?fuente
type([]) is list
regresaTrue
type(x) in [list,tuple]
Es más corto.No hay nada de malo en usar
isinstance
siempre que no sea redundante. Si una variable solo debe ser una lista / tupla, documente la interfaz y simplemente úsela como tal. De lo contrario, un cheque es perfectamente razonable: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 se vincula).
Una verificación explícita a menudo es mejor que intentar usar el objeto como un contenedor y manejar la excepción, que puede causar todo tipo de problemas con el código que se ejecuta parcial o innecesariamente.
fuente
set
objeto también es iterable, lo que significa que si bien seguramente puede extraer elementos de él, pero no garantiza un cierto orden, lo cual es algo muy peligroso para ciertos algoritmos. En los casos en que el orden de los elementos sí importa, ¡un algoritmo que use este fragmento podría generar resultados diferentes en ejecuciones diferentes!Documente el argumento como si fuera una secuencia y úselo como secuencia. No verifique el tipo.
fuente
¿Qué tal
hasattr(a, "__iter__")
:?Indica si el objeto devuelto puede iterarse como un generador. Por defecto, las tuplas y las listas pueden, pero no los tipos de cadena.
fuente
__iter__
.__iter__
por alguna razón ...En Python 2.8
type(list) is list
rendimientosfalse
que sugeriría comparando el tipo en esta horrible manera:
(bueno, al menos en mi sistema, usando anaconda en Mac OS X Yosemite)
fuente
type(list) is list
vuelveFalse
porquetype(list)
estype
, nolist
.type(list()) is list
o con cualquier otra instancia de una lista volveráTrue
.Python utiliza "Mecanografía pato", es decir, si una variable se mueve como un pato, debe ser un pato. En su caso, es probable que desee que sea iterable o que desee acceder al elemento en un índice determinado. Simplemente debe hacer esto: es decir, usar el objeto dentro
for var:
ovar[idx]
dentro de untry
bloque, y si obtiene una excepción, no fue un pato ...fuente
var
se producirá una iteración de cadena con resultados probablemente inesperados.fuente
Si solo necesita saber si puede usar la
foo[123]
notación con la variable, puede verificar la existencia de un__getitem__
atributo (que es lo que Python llama cuando accede por índice) conhasattr(foo, '__getitem__')
fuente
Tiene que ser una prueba más compleja si realmente desea manejar casi cualquier cosa como argumento de función.
Aunque, por lo general, es suficiente explicar que una función espera iterable y luego verificar solo
type(a) != type('')
.También puede suceder que para una cadena tengas una ruta de procesamiento simple o que seas agradable y hagas una división, etc., por lo que no quieres gritar a las cadenas y si alguien te envía algo extraño, solo déjalo tener una excepción.
fuente
Otra forma fácil de averiguar si una variable es lista o tupla o, en general, verificar el tipo de variable sería:
fuente
En principio, estoy de acuerdo con Ignacio, arriba, pero también puede usar el tipo para verificar si algo es una tupla o una lista.
fuente