2010-02-16 8 views
27

Digamos que tenemos una lista:Ordenar una parte de una lista en su lugar

a = [4, 8, 1, 7, 3, 0, 5, 2, 6, 9] 

Ahora, a.sort() ordenará la lista en su lugar. ¿Qué pasa si queremos ordenar solo una parte de la lista, todavía en su lugar? En C++ podríamos escribir:

int array = { 4, 8, 1, 7, 3, 0, 5, 2, 6, 9 }; 
int * ptr = array; 
std::sort(ptr + 1, ptr + 4); 

¿Hay una manera similar en Python?

+0

¿Por qué la necesidad de ordenar solo en el lugar? –

+0

Creo que sería una buena idea solicitar ser agregado a Python. Simplemente serían argumentos opcionales de inicio y finalización del método estándar sort(). –

+0

Una buena razón para el ordenamiento in situ es un caso en el que desea ordenar el final de la lista (que ya está ordenada en su mayoría, tal vez por una función clave menos costosa), y luego mostrar el último valor. Se topó con este caso de uso al construir una solución TSP codiciosa. Es probable que vaya con la solución de @fviktor. – Jostikas

Respuesta

0

Una solución más Pythonic podría ser:

# i,j = range to sort. 
a = a[:i] + sorted(a[i:j]) + a[j:] 

Esto no está ordenada 'en su sitio', pero que parece un requisito artificial. Feliz de saber por qué eso podría ser un requisito, sin embargo. ;)

+20

a [i: j] = ordenado (a [i: j]) parece mejor – SurDin

+1

Bueno, ¿no tendría ese requisito artificial algún sentido si, digamos, la lista es realmente enorme? – Headcrab

+1

@SurDin: publica eso como una respuesta separada, por favor. –

0

En función de sus requisitos, le sugiero que cree su propia clase de función/una clase contenedora para la lista con una función de clasificación que satisfaga sus necesidades.

Puede considerar la expresión DSU o la transformación schwartzian: Consulte http://wiki.python.org/moin/HowTo/Sorting y http://wiki.python.org/moin/PythonSpeed/PerformanceTips. Te sugiero que decores con 0 hasta i, el elemento entre i y j y 0 de nuevo j en adelante. Luego, use una función de comparación personalizada para devolver 0 si x o y es cero, ¡haga que la ordenación funcione! Esto puede no ser de ayuda, ya que hemos cruzado Python V2.4 hace mucho tiempo. Aún así, esto podría ser lo que estás buscando.

Esta respuesta se llena mientras trato de averiguar si se puede hacer con menos esfuerzo.

37

me gustaría escribir de esta manera:

a[i:j] = sorted(a[i:j]) 

no está en el lugar tipo cualquiera, pero lo suficientemente rápido como para segmentos relativamente pequeños.

Tenga en cuenta que Python solo copia referencias de objetos, por lo que la penalización de velocidad no será tan grande en comparación con una ordenación real en el lugar como cabría esperar.

+0

El OP realmente pidió números enteros. Para una matriz de enteros, copiar referencias no debe ser mucho más rápido que copiar los valores reales. – log0

+0

La pregunta no indica que la lista solo puede contener números enteros. El ejemplo de C++ opera de hecho en enteros, pero eso no significa que la pregunta esté limitada solo a eso. – fviktor

12

si a es una matriz numpy entonces para ordenar [i, j) rango en el lugar, tipo:

a[i:j].sort() 

Ejemplo:

>>> import numpy as np 
>>> a = np.array([4, 8, 1, 7, 3, 0, 5, 2, 6, 9]) 
>>> a[1:4].sort() 
>>> a 
array([4, 1, 7, 8, 3, 0, 5, 2, 6, 9]) 
-3

Usted puede simplemente utilizar el método de ordenar la lista, por ejemplo,

>>> a = [2,3,1] 
>>> a.sort() 
>>> a 
[1, 2, 3] 
+2

La pregunta era cómo ordenar _part_ de una lista. – ThomasMcLeod

+0

Si puede ordenar una lista, puede ordenar cada parte de una lista ya que un [i: j] también forma una lista – user107852

2

Hay otro sencillo approach.let tiene una matriz

a = [4, 8, 1, 7, 3, 0, 5, 2, 6, 9] 

y desea ordenar una parte de esta matriz, digamos de índice 2 a 7 índice en un índice basado en cero, es decir, desde el elemento 1 a 2.

b = a[2:7+1] 
b.sort() 
a[2:7+1] = b 
0

Aquí es la referencia de python wiki

BÁSICAL ly, el sorted(list) crea una nueva lista ordenada; sin embargo, el método list.sort() puede ayudarlo a ordenar en el lugar.

>>> list = [(3, 5), (4, 7), (1, 5)] 
    >>> sorted(list) 
    [(1, 5), (3, 5), (4, 7)] 
    >>> list.sort() 
    [(1, 5), (3, 5), (4, 7)] 
Cuestiones relacionadas