¿Existe la posibilidad de crear cualquier objeto Python que no se pueda ordenar? Entonces, ¿esa será una excepción cuando intente ordenar una lista de esos objetos? Creé una clase muy simple, no definí ningún método de comparación, pero aún las instancias de esta clase son comparables y, por lo tanto, se pueden ordenar. Tal vez, mi clase hereda métodos de comparación de algún lado. Pero no quiero este comportamiento.¿Hay alguna manera de crear un objeto python que no se pueda ordenar?
Respuesta
Puede definir un método __cmp__
en la clase y siempre generar una excepción cuando se invoca. Eso podría hacer el truco.
Por curiosidad, ¿por qué?
¿Por qué no simplemente escribe una clase que contiene un objeto de lista y proporciona métodos para acceder a los datos dentro? Al hacerlo, ocultaría efectivamente la lista y, por lo tanto, les impediría clasificarla.
Como Will McCutchen ha mencionado, puede definir un método __cmp__
que genera una excepción para evitar la selección de variedades de jardín. Algo como esto:
class Foo(object):
def __cmp__(self, other):
raise Exception()
a = [Foo(), Foo(), Foo()]
a.sort()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __cmp__
Exception
Sin embargo, no se puede evitar realmente que un desarrollador clasifique una lista de sus objetos. Utilizando el argumento key
o cmp
con list.sort()
o con la función incorporada independiente sorted()
, cualquiera puede eludir el método __cmp__
utilizando una función de comparación personalizada o una clave de clasificación.
# continuing from above
>>> a = [Foo(), Foo(), Foo()]
>>> a
[<__main__.Foo object at 0x1004a3350>, <__main__.Foo object at 0x1004a3390>,
<__main__.Foo object at 0x1004a33d0>]
>>> a.sort(key=id, reverse=True)
>>> # or a.sort(cmp=lambda a, b: cmp(id(b), id(a)))
>>> # or sorted(a, key=id)
>>> # etc...
[<__main__.Foo object at 0x1004a33d0>, <__main__.Foo object at 0x1004a3390>,
<__main__.Foo object at 0x1004a3350>]
Como otros señalarán, no estoy seguro de que tenga mucho valor tratar de evitar que alguien clasifique un objeto. Si esto no es solo una picazón curiosa que intenta rascar, ¿cuál es el caso de uso para esto?
Has sido un minuto más rápido. Casi exactamente el mismo código de ejemplo;) –
La clasificación de lista predeterminada utiliza la función incorporada cmp()
en sus elementos. La función cmp()
comprueba si sus argumentos (2 elementos de su lista) tienen un método __cmp__()
. Si es así, este método se usa para comparar. De lo contrario, como en su caso, los identificadores de objeto del argumento (valor de retorno de la función incorporada id()
) se utilizan para la comparación.
Para permitir la clasificación fallan, se podría definir un método de comparación que se produce una excepción:
>>> class X(object):
... def __cmp__(self, other):
... raise StandardError # or whatever Exception you need
...
>>> l = [X(), X(), X()]
>>> l.sort()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in __cmp__
StandardError
¡Esa es una respuesta agradable y clara! Pero, ¿tiene algún objeto una función incorporada id()? – Graf
ID de objetos se establece internamente por Python, no por el método de un objeto. Típicamente, v.g. en Python basado en C, es simplemente la dirección de memoria del objeto (ver también http://docs.python.org/library/functions.html#id). –
conjuntos no tienen un total de ordenar
>>> s=set((1,2,3))
>>> t=set("abc")
>>> s<t
False
>>> t<s
False
>>>
Pero no es una excepción es aumentar cuando intente ordenarlos
>>> sorted([s,t])
[set([1, 2, 3]), set(['a', 'c', 'b'])]
Por lo que vale, en Python 3 el valor predeterminado será para el nuevo ems para no ser comparable (y por lo tanto no se puede ordenar). En Python 2, tiene que crear explícitamente un método __cmp__
o __lt__
, como han dicho otros.
Los algoritmos de ordenación python utilizan el método especial __lt__
. Teniendo en cuenta que el uso de los cmp
key
y argumentos de la función y los métodos de clasificación, se sugiere que su clase define un método:
def __lt__(self, other):
raise NotImplementedError
- 1. ¿Hay alguna manera de hacer que TFS se pueda enlazar?
- 2. ¿Hay alguna manera de hacer que el texto no se pueda seleccionar en una página HTML?
- 3. ¿Hay alguna manera de hacer que un enlace se pueda hacer clic en el terminal OSX?
- 4. ¿Hay alguna herramienta que pueda incorporar CSS?
- 5. ¿Hay alguna manera de crear complementos de Eclipse con Python?
- 6. ¿Hay alguna manera de ignorar un caso que no coincide?
- 7. Crear un objeto python al que se pueda acceder con corchetes
- 8. ¿Hay alguna manera de inicializar un objeto mediante un hash?
- 9. Python/Matplotlib - ¿Hay alguna manera de hacer un eje discontinuo?
- 10. ¿Hay alguna manera de que una actividad sepa qué fragmento se acaba de crear?
- 11. ¿Hay alguna manera de hacer que python se convierta en interactivo en medio de un script?
- 12. ¿Hay alguna manera de ordenar cadenas en todos los idiomas?
- 13. ¿Hay alguna manera de clasificar/ordenar claves en objetos JavaScript?
- 14. ¿Hay alguna manera de crear un DynamicObject que admita una interfaz?
- 15. ¿Hay alguna manera en que pueda hacer que g ++ solo emita advertencias relacionadas con mis archivos?
- 16. ¿Hay alguna heurística de relleno de CSS que pueda seguir?
- 17. ¿Hay alguna manera de que pueda cambiar el orden de carga de Apache VirtualHosts primero?
- 18. ¿Hay alguna manera de que pueda definir una variable en LaTeX?
- 19. ¿Hay alguna clase de C++ que no se pueda usar en STL?
- 20. ¿Hay alguna manera rápida de crear un conjunto?
- 21. ¿Hay alguna manera de que pueda imprimir Array cadena sin necesidad de utilizar para el lazo?
- 22. ¿Hay alguna forma en que pueda hacer dos lecturas atómicas?
- 23. Rails + Devise - ¿Hay alguna manera de BANAR a un usuario para que no pueda iniciar sesión o restablecer su contraseña?
- 24. ¿Alguna manera fácil de trazar una dispersión en 3D en Python que pueda rotar?
- 25. ¿Hay alguna manera de hacer que python pickle ignore los errores de "no es el mismo objeto"
- 26. ¿Hay alguna herramienta de generación de diseño basada en CSS que se pueda arrastrar y soltar?
- 27. ¿Hay alguna manera de identificar un método heredado en Python?
- 28. ¿Hay alguna manera de despertar un hilo que duerme?
- 29. ¿Cómo crear un decorador de Python que se pueda usar con o sin parámetros?
- 30. ¿Hay alguna manera de manejar las funciones no definidas que se invocan en JavaScript?
Gracias por la respuesta rápida! Encontré una receta sobre la manera más rápida de eliminar duplicados de una secuencia - http://code.activestate.com/recipes/52560/. Revise este comentario en el código: "Si no es posible, los elementos de secuencia deben disfrutar de un total de ordenando, y si list (s) .sort() no genera TypeError es se supone que disfrutan de un total de pedidos. unique() será que generalmente funciona en O (N * log2 (N)) tiempo. " No puedo crear un elemento que no disfrute de un orden total. Entonces, ¿es un error del autor de la receta, o él realmente sabe algo, que yo no sé? – Graf
¿Por qué no usar 'set()' para obtener una lista-er, 'conjunto'-de elementos únicos? ¿Por qué estás usando esa receta? Si está usando esa receta y hace que sus objetos siempre presenten una excepción cuando se ordenan, usará la tercera y peor forma de determinar los elementos únicos. –
Sí, entiendo eso, solo quiero saber, si el autor de la receta está haciendo algo de la nada, o si solo trata de manejar todas las situaciones posibles. Así que quiero saber, ¿en qué casos falla la segunda solución (utilizando ordenar) falla? La primera solución falla cuando los objetos no son lavables (por ejemplo, ordenando la lista), pero parece que no hay ningún caso cuando falla la segunda solución. Por cierto, su solución (use set() para obtener una lista-er) también falla en caso de que no haya listas con hashable. >>> a = [[1,1,1], [1,2], [1,1]] >>> a = list (set (a)) TypeError: unhashable type: 'list' – Graf