En python hay una manera fácil de saber si algo no es una secuencia? He intentado hacer:
if x is not sequence pero python no le gustó que

  • Relacionado: En python, ¿cómo determinar si una variable es Iterable? stackoverflow.com/questions/1952464/…
  • Sí, pero mientras que todas las secuencias están iterables no todos los iterables son secuencias (conjuntos y dicts están integradas en iterable los recipientes que no son secuencias, por ejemplo).
InformationsquelleAutor nicotine | 2010-05-30

7 Comentarios

  1. 68

    iter(x) levantará un TypeError si x no se puede afirmar en — pero que el cheque «acepta» conjuntos y diccionarios, a pesar de que «rechaza» otros no-secuencias, tales como None y números.

    En las manos de otros, las cadenas (que la mayoría de las aplicaciones que desee considerar «los elementos individuales» en lugar de secuencias) son en el hecho de secuencias (por lo tanto, cualquier prueba, a menos que specialcased para las cadenas, se va a confirmar que son). Por lo tanto, tales comprobaciones simples son a menudo no es suficiente.

    En Python 2.6 y mejor, clases base abstractas se introdujeron, y entre otras características de gran alcance que ofrecen más bien, un apoyo sistemático a los dichos de la categoría de «comprobación».

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

    Tenga en cuenta que las cadenas son todavía considera «una secuencia» (ya que son), pero al menos se obtiene dicts y conjuntos de la forma. Si desea excluir de cadenas a partir de su concepto de «secuencias», podría utilizar collections.MutableSequence (pero que también excluye a las tuplas que, al igual que las cadenas 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)

    Salpimentar a gusto y servir caliente!-)

    • Tenga en cuenta que este ejemplo de código se devolverá el mal resultado para los objetos que implementan la secuencia de protocolo, pero no implican la collections.Sequence ABC.
    • Sí: a diferencia de la simple Abecedario, la Secuencia no implementar un __subclasshook__ método de clase, por lo que nunca va a reconocer automáticamente una clase que optó por no register con él (o heredar de ella), sería prácticamente imposible contar con la introspección si una clase __getitem__ acepta enteros o en rodajas, plantea IndexError en mal índices, etc-todo lo que necesita para descartar dict y set, esencialmente (que hacer parece a «implementar la secuencia de protocolo» si usted acaba de hacer introspección… pero luego no!-).
    • Los conjuntos son bastante fáciles de descartar, puesto que no tienen __getitem__, pero asignaciones son mucho más difíciles. La mejor comprobación de que he visto es probablemente para buscar keys, como dict.update, pero que aún deja mucho que desear.
    • Así que por mi tipo personalizado a ser detectado como una Secuencia tengo subclase de la Secuencia?
    • Buen ejemplo de la advertencia mencionada es la de los arrays de numpy, que tiene todas las propiedades necesarias de una Secuencia, pero no reconocidos como tales por isinstance. Si esto no funciona aún para arrays de numpy, parece bastante desesperado.
    • En la mayoría de los casos prácticos, str debe no ser considerado como una secuencia, que es la razón por la hasattr(str,'__iter__') devuelve false.
    • las necesidades de una secuencia. OrderedDict implementa reversed, y sin embargo isinstance(OrderedDict(), Sequence) es False. Me pregunto por qué.

  2. 10

    Creo que el siguiente fragmento de código hace lo que quiere:

    def is_sequence(obj):
        return hasattr(type(obj), '__iter__')
    • Debe ser hasattr(type(obj), '__iter__'), consulte este comentario.
    • Este es un muy universal variante ya que no está relacionado con la herencia de clases específicas. Funciona para el diccionario de secuencias de teclas también.
    • una cadena que iba a pasar esta prueba. hasattr(type("foo"), '__iter__') => True
  3. 6

    Desde Python «se adhiere» duck typing, uno de los enfoque es comprobar si un objeto tiene algún miembro (método).

    Una secuencia de longitud, tiene una secuencia de elementos, y el apoyo de rebanar [doc]. Así, sería como este:

    def is_sequence(obj):
        t = type(obj)
        return hasattr(t, '__len__') and hasattr(t, '__getitem__')
        # additionally: and hasattr(t, '__setitem__') and hasattr(t, '__delitem__')

    Todos ellos son métodos especiales, __len__() debe devolver el número de elementos, __getitem__(i) debe devolver un artículo (en la secuencia es me-ésimo elemento, pero no con la asignación), __getitem__(slice(start, stop, step)) debe devolver larga y __setitem__ y __delitem__ como se espera. Este es un contrato, pero si el objeto realmente estas o no depende de si el objeto se adhiere el contrato o no.

    Nota que, la función de arriba también vuelve True para la asignación, por ejemplo,dict, desde el mapeo también tiene estos métodos. Para superar esto, se puede hacer un más pesado trabajo:

    def is_sequence(obj):
        try:
            len(obj)
            obj[0:0]
            return True
        except TypeError:
            return False

    Pero la mayoría del tiempo usted no necesita esto, simplemente hacer lo que quieres como si el objeto es una secuencia y atrapar una excepción si usted desea. Esto es más python.

    • El punto importante acerca de dict es que si te tratan como a una secuencia que acaba de conseguir las llaves, no en los valores, y se pierde la información.
    • Si el uso de hasattr(), usted necesita para comprobar el tipo de objeto para que la magia de los métodos, no el objeto en sí. Consulte el Python 2 y Python 3 documentación sobre cómo los métodos especiales se levantó la vista.
    • Gracias man
    • __setitem__ y __delitem__ se aplicaría únicamente a los secuencias (por ejemplo, no tupla o de cadena)
  4. 5

    La Python 2.6.5 documentación describe los siguientes tipos de secuencia: cadena, cadena Unicode, lista, tupla, buffer, y xrange.

    def isSequence(obj):
        return type(obj) in [str, unicode, list, tuple, buffer, xrange]
    • El problema con esta respuesta es que no va a detectar las secuencias que no están integrados tipos. Python «secuencia» es cualquier objeto que implementa los métodos necesarios para responder a la secuencia de operaciones.
    • También, el uso de isinstance en lugar de type para apoyar a las subclases.
  5. 1

    Para Python 3 y 2.6+, usted puede comprobar si es una subclase de collections.Sequence:

    >>> import collections
    >>> isinstance(myObject, collections.Sequence)
    True

    En Python 3.7 debe utilizar collections.abc.Sequence (collections.Sequence será eliminado en Python 3.8):

    >>> import collections.abc
    >>> isinstance(myObject, collections.abc.Sequence)
    True

    Sin embargo, esto no funciona para pato-escribió secuencias que implementar __len__() y __getitem__() pero no (como se debe) subclase collections.Sequence. Pero funcionará para todo el built-in de Python tipos de secuencia: listas, tuplas, cadenas, etc.

    Mientras que todas las secuencias están iterables, no todos los iterables son secuencias (por ejemplo, conjuntos y diccionarios son iterable, pero no de las secuencias). La comprobación de hasattr(type(obj), '__iter__') volverá True para los diccionarios y conjuntos.

  6. -1

    ¿Por qué estás haciendo esto? La forma normal aquí es que requieren un cierto tipo de cosa (Una secuencia o un número o un archivo como objeto, etc.) y, a continuación, utilizarlo sin comprobar nada. En Python, no suelen utilizar clases para llevar la información semántica, sino simplemente el uso de los métodos definidos (esto se llama «duck typing»). También preferimos Api donde sabemos exactamente qué esperar, el uso de palabras clave argumentos, preprocesamiento, o la definición de otra función si desea cambiar cómo funciona una función.

    • Es una asignación de restricción. Si el argumento que se pasa no es un int, long o secuencia que necesita para criar a un TypeError
    • reconocer que esta asignación indica un diseño que es generalmente nonidiomatic y frágil. Considere el caso normal, donde un objeto debe ser exactamente el tipo de cosa. Si un parámetro se supone que es una secuencia, sino que recibe un int, cuando el índice o iterar a través de ella se obtuvo una TypeError. Del mismo modo, si usted trató de hacer operaciones con números enteros con una secuencia de usted.
    • Proporcionar un API consistente (cuando sea posible) que espera sólo un tipo de cosa que te permite escribir más simple código que todavía genera errores cuando algo sale mal, pero es más robusto que soporta los tipos de no pensar sino satisfacer el verdadero objetivo (por ejemplo, alguna costumbre de la clase que implementa __len__ y __getitem__ funcionaría como una secuencia.)
    • Para dar un ejemplo de por donde tal cosa podría ser útil, estoy tratando de escribir una función que puede ser dado a un objeto de un tipo o de una lista (o tupla) de tales objetos, y tengo que ser capaz de detectar si la persona que me dio una secuencia o un solo objeto. Sé que es discutible si esto es o no es un buen diseño, pero por el momento no puedo pensar en nada de lo que habla en contra de ella.
    • La mejor solución por el momento es tener una función de hacer una cosa, no para varias cosas. Siempre requieren de una secuencia, por ejemplo. (Usted puede hacer una segunda función API diferente.) El problema es que no hay una Buena manera de detectar la diferencia en Python y que es más difícil comprender las funciones que hacer varias cosas en lugar de una cosa.
    • A veces es inevitable. Estoy lidiando con una situación en la que estoy de procesamiento de datos JSON en los que un determinado valor puede ser una cadena, un entero o una lista de números enteros. Yo no puedo cambiar el JSON generador, así que tengo que manejar los datos como se trata de mí.
    • Sin la comprobación de que va a llegar un TypeError excepción en algún momento, sin embargo este me lanza fuera de mi flujo normal de mi código. Por la comprobación de que me puede mitigar este problema con mucho más control de lo que hacer en este inválida situación. Esto es en realidad una discusión acerca de si el uso o no de las excepciones como un error de mecanismo de control. Siempre he estado en contra de ello, también existen múltiples lenguas modernas que no admiten excepciones (cualquiera)más. Desafortunadamente, el uso de las excepciones es el Python el camino, por lo que idiomáticamente que son (por desgracia) a la derecha.

  7. -3

    ¿por qué preguntar por qué

    tratar de conseguir una longitud y si excepción return false

    def haslength(seq):
        try:
            len(seq)
        except:
            return False
        return True
    • Un set tiene una longitud pero no es una secuencia.

Dejar respuesta

Please enter your comment!
Please enter your name here