Estoy tratando de escribir un código más simple para agregar elementos únicos a una lista de Python. Tengo un conjunto de datos que contiene una lista de diccionarios, y estoy tratando de iterar a través de una lista dentro del diccionario.

¿Por qué esto no funciona? Está agregando todos los elementos, incluidos los duplicados, en lugar de agregar elementos únicos.

unique_items = []
unique_items = [item for d in data for item in d['items'] if item not in unique_items]

Vs. la forma más larga que funciona:

unique_items = []
for d in data:
    for item in d['items']:
        if (item not in unique_items):
            unique_items.append(item)

¿Hay alguna manera de hacer que esto funcione usando la comprensión de listas, o estoy atascado con el uso de double for loops? Quiero seguir ordenando esto.

Aquí está la lista de diccionarios:

[{"items":["apple", "banana"]}, {"items":["banana", "strawberry"]}, {"items":["blueberry", "kiwi", "apple"]}]

La salida debe ser ["manzana", "plátano", "fresa", "arándano", "kiwi"]

Me di cuenta de que alguien hizo una pregunta similar en otra publicación: Comprensión de la lista de Python, con elementos únicos, pero me preguntaba si hay otra forma de hacerlo sin OrderedDict o si esa es la mejor manera

3
user3226932 14 may. 2016 a las 03:36

3 respuestas

La mejor respuesta

La forma más fácil es usar OrderedDict:

from collections import OrderedDict
from itertools import chain

l = [{"items":["apple", "banana"]}, {"items":["banana", "strawberry"]}, {"items":["blueberry", "kiwi", "apple"]}]
OrderedDict.fromkeys(chain.from_iterable(d['items'] for d in l)).keys() # ['apple', 'banana', 'strawberry', 'blueberry', 'kiwi']

Si desea alternativas, marque OrderedSet receta y paquete basado en él.

1
niemmi 14 may. 2016 a las 01:17

¿Por qué no solo usar set?

P.ej. -

>>> data = {1: {'items': [1, 2, 3, 4, 5]}, 2: {'items': [1, 2, 3, 4, 5]}}
>>> {val for item in data for val in data[item]['items']}
>>> {1, 2, 3, 4, 5}

Si quieres una lista:

>>> list(repeat above)
>>> [1, 2, 3, 4, 5]

En lugar de las llaves {} para el conjunto, también podría usar la palabra clave set, ya que las llaves pueden ser demasiado oscuras para algunos.

Aquí hay un enlace a la sintaxis

2
Pythonista 14 may. 2016 a las 00:42

all_items no se sobrescribe continuamente durante la comprensión de la lista, por lo que constantemente está buscando cosas en una lista vacía.

Yo haría esto en su lugar:

data = [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 4,]

items = []
_ = [items.append(d) for d in data if d not in items]
print(items)

Y obtengo:

[1, 2, 3, 4, 5, 6]

Pero hay formas más eficientes de hacer esto de todos modos.

3
Paul H 14 may. 2016 a las 00:42