En python, ¿hay alguna manera fácil de saber si algo no es una secuencia? Traté de Just Do: if x is not sequence
pero Python no les gustaba quePython: compruebe si un objeto es una secuencia
Respuesta
iter(x)
elevará un TypeError
si x
no se pueden repetir en - pero eso verificación "acepta" conjuntos y diccionarios, a pesar de que "rechaza" otros no-secuencias como None
y números.
En las otras manos, cuerdas (que la mayoría de las aplicaciones que desee considerar "elementos individuales" en lugar de secuencias) son en las secuencias de hechos (así, cualquier prueba, a menos que specialcased para cuerdas, se va a confirmar que se encuentran) . Entonces, tales controles simples a menudo no son suficientes.
En Python 2.6 y mejor, se introdujeron las clases base abstractas, y entre otras características potentes ofrecen un soporte más bueno y sistemático para dicha "verificación de categoría".
>>> import collections
>>> isinstance([], collections.Sequence)
True
>>> isinstance((), collections.Sequence)
True
>>> isinstance(23, collections.Sequence)
False
>>> isinstance('foo', collections.Sequence)
True
>>> isinstance({}, collections.Sequence)
False
>>> isinstance(set(), collections.Sequence)
False
Se habrá dado cuenta cadenas son aún considera "una secuencia" (ya que son ), pero al menos se consiguen dicts y conjuntos fuera del camino. Si desea excluir cuerdas de su concepto de "ser secuencias", podría utilizar collections.MutableSequence
(pero que también excluye tuplas, que, como cuerdas, son secuencias, pero no son mutables), o hacerlo de forma explícita:
import collections
def issequenceforme(obj):
if isinstance(obj, basestring):
return False
return isinstance(obj, collections.Sequence)
Sazonar al gusto, y servir caliente! -)
Tenga en cuenta que este ejemplo de código arrojará el resultado incorrecto para los objetos que implementan el protocolo de secuencia, pero no involucran el ABC 'collections.Sequence'. –
Sí: a diferencia de un ABC más simple, Sequence no implementa un método de clase '__subclasshook__', por lo que nunca reconocerá automáticamente una clase que eligió no 'registrar' con él (o heredar de él) - sería esencialmente imposible decir por introspección si el '' __getitem__' de una clase acepta enteros y sectores, levanta 'IndexError' en índices incorrectos, etc. - todo lo que necesita para descartar' dict' y 'set', esencialmente (que _do_ parece" implementar la secuencia protocolo "si solo haces introspección ... pero luego no!"). –
Los conjuntos son bastante fáciles de descartar, ya que no tienen '__getitem__', pero las asignaciones son mucho más difíciles. El mejor control que he visto es probablemente buscar 'keys', como' dict.update', pero eso aún deja mucho que desear. – user2357112
¿Por qué haces esto? La forma normal aquí es requerir cierto tipo de cosas (una secuencia o un número o un objeto parecido a un archivo, etc.) y luego usarlo sin verificar nada. En Python, normalmente no usamos clases para llevar información semántica, sino que simplemente usamos los métodos definidos (esto se llama "tipa de pato"). También preferimos las API donde sabemos exactamente qué esperar; utilice argumentos de palabra clave, preprocesamiento o defina otra función si desea cambiar el funcionamiento de una función.
Es una restricción de asignación. Si el argumento que se nos pasa no es un int, largo o secuencia, necesitamos generar un 'TypeError' – nicotine
@nicotine, reconocemos que esta asignación indica un diseño que generalmente no es ficticio ni frágil. Considere el caso normal, donde un objeto debería ser exactamente un tipo de cosa. Si se supone que un parámetro es una secuencia, pero obtienes un int, cuando indexas o iteras sobre él ya obtendrás un 'TypeError'. De manera similar, si intentas realizar operaciones de enteros con una secuencia, lo harías. –
Proporcionando una API consistente (cuando sea posible) que espera un solo tipo de cosas le permite escribir un código más simple que aún genera errores cuando algo sale mal pero es más robusto porque admite tipos en los que no pensó pero que satisfacen los verdaderos objetivo (por ejemplo, una clase personalizada que implementa '__len__' y' __getitem__' funcionaría como una secuencia.) –
El Python 2.6.5 documentation describe los siguientes tipos de secuencia: cadena, cadena Unicode, lista, tupla, búfer y xrange.
def isSequence(obj):
return type(obj) in [str, unicode, list, tuple, buffer, xrange]
El problema con esta respuesta es que no detectará secuencias que no sean tipos incorporados. Una "secuencia" de Python es cualquier objeto que implementa los métodos necesarios para responder a las operaciones de secuencia. – intuited
Además, use 'isinstance' en lugar de' type' para admitir subclases. – bfontaine
qué preguntarse por qué
intentar conseguir una longitud y si excepción return false
def haslength(seq):
try:
len(seq)
except:
return False
return True
Un 'conjunto' tiene una longitud pero no es una secuencia. – bfontaine
Como Python "se adhiere" duck typing, uno de los enfoque es comprobar si un objeto tiene alguna miembro (método).
Una secuencia tiene longitud, tiene una secuencia de elementos y admite el corte [doc]. Por lo tanto, sería así:
def is_sequence(obj):
t = type(obj)
return hasattr(t, '__len__') and hasattr(t, '__getitem__')
# additionally: and hasattr(t, '__setitem__') and hasattr(t, '__delitem__')
Son todos los métodos especiales, __len__()
debe devolver número de elementos, __getitem__(i)
debería devolver un artículo (en secuencia es i -ésimo, pero no con mapeo), __getitem__(slice(start, stop, step))
debe devolver subsecuencia y __setitem__
y __delitem__
como usted espera.Este es un contrato de este tipo, pero si el objeto realmente hace esto o no depende de si el objeto se adhiere o no al contrato.
Nota que, la función anterior también devolverá True
para el mapeo, p. Ej. dict
, ya que la asignación también tiene estos métodos. Para superar esto, se puede hacer un más pesado el trabajo:
def is_sequence(obj):
try:
len(obj)
obj[0:0]
return True
except TypeError:
return False
Pero mayor parte del tiempo que no necesita esto, simplemente hacer lo que quiera como si el objeto es una secuencia y capturar una excepción si lo desea. Esto es más pitónico.
El punto importante acerca de dict es que si lo trata como una secuencia, obtendrá las claves, no los valores, y la información se perderá. –
Si usa 'hasattr()', necesita verificar el tipo del objeto para los métodos mágicos, no el objeto en sí. Consulte [Python 2] (https://docs.python.org/2/reference/datamodel.html#special-method-lookup-for-new-style-classes) y [Python 3] (https: // docs .python.org/3/reference/datamodel.html # special-method-searchup) documentación sobre cómo se buscan los métodos especiales. – augurar
@augurar Thanks man – BornToCode
creo que el siguiente fragmento de código hace lo que quiere:
def is_sequence(obj):
return hasattr(type(obj), '__iter__')
Debería ser 'hasattr (type (obj), '__iter __')', ver [este comentario] (https://stackoverflow.com/questions/2937114/#comment71833903_31043360). – augurar
- 1. Compruebe si un objeto es un delegado
- 2. compruebe si un objeto es nulo
- 3. Compruebe si un objeto es una colección genérica
- 4. Mangosta: compruebe si el objeto es un objeto de mangosta
- 5. Compruebe si un objeto es un NSArray o NSDictionary
- 6. Compruebe si un elemento está dentro de una secuencia
- 7. Compruebe si objeto es una instancia de modelo sqlalchemy
- 8. Compruebe si existe un objeto en VBScript
- 9. Compruebe si el objeto Ruby es un booleano
- 10. jQuery: compruebe si un objeto tiene clase
- 11. Compruebe si un archivo PDF es válido (Python)
- 12. compruebe si una cadena es una URL
- 13. Compruebe si una variable es una matriz
- 14. python 3: cómo verificar si un objeto es una función?
- 15. Compruebe si un argumento es una lista o un átomo
- 16. Compruebe si una fecha determinada es anterior
- 17. Compruebe si es seguro eliminar una fila
- 18. compruebe si un archivo es ejecutable
- 19. Compruebe si el valor es un número
- 20. NSMutableArray compruebe si el objeto ya existe
- 21. Hibernar: compruebe si existe el objeto
- 22. Compruebe si stderr es una tubería en bash
- 23. Compruebe si un UITableViewCell específico es visible en una UITableView
- 24. Compruebe si un entero es una potencia entera de otro
- 25. Compruebe si un usuario es root en una aplicación java
- 26. Compruebe si una matriz es un subconjunto de otra
- 27. Python: compruebe si el archivo cargado es jpg
- 28. Compruebe si se define un objeto, mejor práctica.
- 29. Python: determinar si un objeto es similar a un archivo
- 30. Django: compruebe si ya existe un objeto antes de agregar
relacionada: En Python, ¿cómo puedo determinar si una variable es Iterable? http://stackoverflow.com/questions/1952464/in-python-how-do-i-determine-if-a-variable-is-iterable/1952481#1952481 – miku
Sí, pero si bien todas las secuencias son iterables, no todos los iterables son secuencias (sets y dicts son contenedores integrados que no son secuencias, por ejemplo). –