recuperando los elementos de la lista: python

Probablemente una pregunta muy ingenua:

Tengo una lista:

color = ["red","blue","red","green","blue"]

Ahora, quiero iterar a través de la lista

for c in color:
   # color is "red"
     get the rest of the colors except this red
    so rest = ["blue","red","green",blue"]

en la próxima iteración:

    c = blue
    rest = ["red","red","green","blue"]

Eh ¿Por qué tengo la sensación de que esto es bastante trivial de hacer... y probablemente haya un comando de una línea que pueda resolver esto? Gracias

preguntado el 03 de mayo de 12 a las 21:05

¿Estás buscando list.pop()? Elimina y devuelve un elemento de una lista. -

6 Respuestas

La forma más fácil de pensar en esto es que desea iterar a través de cada combinación con una longitud menor que la lista. Para hacer esto, podemos usar itertools.combinations():

import itertools

color = ["red","blue","red","green","blue"]

for rest in itertools.combinations(color, len(color)-1):
    print(rest)

Lo que nos da:

('red', 'blue', 'red', 'green')
('red', 'blue', 'red', 'blue')
('red', 'blue', 'green', 'blue')
('red', 'red', 'green', 'blue')
('blue', 'red', 'green', 'blue')

Esta es una buena solución ya que funciona tanto en iterables como en secuencias, es muy legible y debería ser agradable y rápido.

Si también necesita el valor actual, también puede obtenerlo fácilmente, ya que combinations() le da un orden predecible, por lo que simplemente iteramos a través de ambos al mismo tiempo con zip() (naturalmente, si desea obtener el mejor rendimiento, utilice itertools.izip() bajo Python 2.x, como zip() crea una lista, no un generador como en 3.x).

import itertools

color = ["red","blue","red","green","blue"]

for c, rest in zip(color, itertools.combinations(reversed(color), len(color)-1)):
    print(c, rest)

red ('blue', 'green', 'red', 'blue')
blue ('blue', 'green', 'red', 'red')
red ('blue', 'green', 'blue', 'red')
green ('blue', 'red', 'blue', 'red')
blue ('green', 'red', 'blue', 'red')

Aquí invierto la entrada para comibinations() por lo que funciona de izquierda a derecha, puede invertir color en la zip() en lugar de ir de derecha a izquierda.

Entonces sí, en resumen, es una solución de una línea (dos si cuenta la importación).

contestado el 03 de mayo de 12 a las 21:05

La implementación actual de combinations() podría dar un orden predecible, pero no confiaría en que siga siendo el mismo en implementaciones futuras. - spinlok

@spinlok El pedido de combinaciones Está garantizado. - raymond hettinger

@spinlok Es un característica documentada de la función - sería un cambio radical cambiarlo. - gareth latty

Rebanar y enumerar facilitar el trabajo de esta tarea:

>>> colors = ["red", "blue", "red", "green", "blue"]
>>> for i, color in enumerate(colors):
        rest = colors[:i] + colors[i+1:]
        print color, '-->', rest

red --> ['blue', 'red', 'green', 'blue']
blue --> ['red', 'red', 'green', 'blue']
red --> ['red', 'blue', 'green', 'blue']
green --> ['red', 'blue', 'red', 'blue']
blue --> ['red', 'blue', 'red', 'green']

La enumerar rastrea la posición de cada color y los cortes extraen las partes de la lista antes y después del color.

contestado el 03 de mayo de 12 a las 21:05

@AshwiniChaudhary En realidad, cortar tan rápido o más rápido que cualquier otro método para crear una lista (gran parte del código para list(s), l.extend(s) y l[:] = s es el mismo código subyacente). Además, el corte predimensionará la lista de objetivos para que no sea necesario cambiar el tamaño. IOW, usted menos uno no solo es injustificado, es simplemente incorrecto. - raymond hettinger

perdón por el comentario incompleto, lo que quise decir es que el corte es una forma más fácil, pero su solución es lenta porque está agregando dos listas usando '+', lo que lo hace lento. ¿Me equivoco aquí? - Ashwini Chaudhary

Esto también debería funcionar

for i in range(len(yourlist)):
    newlist = yourlist[:i] + yourlist[i:]

contestado el 03 de mayo de 12 a las 21:05

Este código de Python creará una nueva lista de salida sin los duplicados.

done = []
for c in color:
    if c in done:
        continue
    done.append(c)
    print c

Respondido 16 Jul 12, 14:07

El siguiente ejemplo devolverá una lista con los duplicados eliminados. Comienza con una lista de devolución vacía, comprueba la lista de colores y, si un color, en este caso el rojo, ya está en la salida, se ignora.

#!/usr/bin/env python

color = ["red","blue","red","green","blue"]

def rem_dup(dup_list):
    corrected_list = []
    for color in dup_list:
        if color in corrected_list:
            continue
        else:
            corrected_list.append(color)

    return corrected_list

Probablemente sería mejor usar algo como

>>> set(color)
set(['blue', 'green', 'red'])
>>> 

or

>>> import collections
>>> color = ["red","blue","red","green","blue"]
>>> collections.OrderedDict.fromkeys(color)
OrderedDict([('red', None), ('blue', None), ('green', None)])
>>> 

para eliminar los duplicados. Ambos son más eficientes que el bucle for.

Respondido 16 Jul 12, 15:07

for idx, item in enumerate(color):
    print 'I am %s' % item
    rest = color[:idx] + color[idx+1:]
    print 'Rest is %s' % ','.join(rest)

contestado el 03 de mayo de 12 a las 21:05

@AshwiniChaudhary, no, no lo es. Me abstendría de votar negativamente en base a un conocimiento inexacto. - spinlok

su solución es lenta porque está agregando dos listas usando '+', lo he cronometrado usando timeit módulo, compruebe mi solución. - Ashwini Chaudhary

El hecho de que pueda ser lento no significa que sea muy lento. Es posible que no haya votado a favor de la respuesta, pero no veo ninguna razón para votar a la baja. - Chepner

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.