eliminar - identificar elementos repetidos en una lista python
Python: elimine las tuplas duplicadas de la lista si son exactamente el mismo orden de artÃculos incluido (6)
El uso de un set probablemente debería funcionar. Un conjunto es básicamente un contenedor que no contiene ningún elemento duplicado.
Python también incluye un tipo de datos para conjuntos. Un conjunto es una colección desordenada sin elementos duplicados. Los usos básicos incluyen la prueba de membresía y la eliminación de entradas duplicadas. Los objetos establecidos también admiten operaciones matemáticas como unión, intersección, diferencia y diferencia simétrica.
import itertools
x = [1,1,1,2,2,2,3,3,3,4,4,5]
y = set()
for x in itertools.combinations(x,3):
y.add(x)
print(y)
Sé que preguntas similares a esto se han formulado muchas, muchas veces en Desbordamiento de pila, pero necesito eliminar tuplas duplicadas de una lista, pero no solo si sus elementos coinciden, sus elementos tienen que estar en el mismo orden. En otras palabras, (4,3,5)
y (3,4,5)
estarían presentes en la producción, mientras que si hubiera tanto (3,3,5)
como (3,3,5)
, solo una Estaría en la salida.
Específicamente, mi código es:
import itertools
x = [1,1,1,2,2,2,3,3,3,4,4,5]
y = []
for x in itertools.combinations(x,3):
y.append(x)
print(y)
de los cuales la salida es bastante larga. Por ejemplo, en la salida, debería haber ambos (1,2,1)
y (1,1,2)
. Pero solo debe haber uno (1,2,2)
.
Esto probablemente hará lo que quieras, pero es un exceso excesivo. Es un prototipo de bajo nivel para un generador que puede agregarse a sus itertools
algún día. Es de bajo nivel para facilitar la reimplementación en C. Donde N
es la longitud de la entrada iterable, requiere el espacio en el peor de los casos O(N)
y hace como máximo N*(N-1)//2
comparaciones de elementos, independientemente De cuántos anagramas se generan. Ambos son óptimos ;-)
Lo usarías así:
>>> x = [1,1,1,2,2,2,3,3,3,4,4,5]
>>> for t in anagrams(x, 3):
... print(t)
(1, 1, 1)
(1, 1, 2)
(1, 1, 3)
(1, 1, 4)
(1, 1, 5)
(1, 2, 1)
...
No habrá duplicados en la salida. Nota: este es el código de Python 3. Necesita algunos cambios para ejecutarse bajo Python 2.
import operator
class ENode:
def __init__(self, initial_index=None):
self.indices = [initial_index]
self.current = 0
self.prev = self.next = self
def index(self):
"Return current index."
return self.indices[self.current]
def unlink(self):
"Remove self from list."
self.prev.next = self.next
self.next.prev = self.prev
def insert_after(self, x):
"Insert node x after self."
x.prev = self
x.next = self.next
self.next.prev = x
self.next = x
def advance(self):
"""Advance the current index.
If we''re already at the end, remove self from list.
.restore() undoes everything .advance() did."""
assert self.current < len(self.indices)
self.current += 1
if self.current == len(self.indices):
self.unlink()
def restore(self):
"Undo what .advance() did."
assert self.current <= len(self.indices)
if self.current == len(self.indices):
self.prev.insert_after(self)
self.current -= 1
def build_equivalence_classes(items, equal):
ehead = ENode()
for i, elt in enumerate(items):
e = ehead.next
while e is not ehead:
if equal(elt, items[e.indices[0]]):
# Add (index of) elt to this equivalence class.
e.indices.append(i)
break
e = e.next
else:
# elt not equal to anything seen so far: append
# new equivalence class.
e = ENode(i)
ehead.prev.insert_after(e)
return ehead
def anagrams(iterable, count=None, equal=operator.__eq__):
def perm(i):
if i:
e = ehead.next
assert e is not ehead
while e is not ehead:
result[count - i] = e.index()
e.advance()
yield from perm(i-1)
e.restore()
e = e.next
else:
yield tuple(items[j] for j in result)
items = tuple(iterable)
if count is None:
count = len(items)
if count > len(items):
return
ehead = build_equivalence_classes(items, equal)
result = [None] * count
yield from perm(count)
Estuviste muy cerca Solo obtén permutaciones, no combinaciones. El orden importa en las permutaciones, y no lo hace en combinaciones. Por lo tanto (1, 2, 2) es una permutación distinta de (2, 2, 1). Sin embargo (1, 2, 2) se considera una combinación singular de uno 1 y dos 2s. Por lo tanto (2, 2, 1) no se considera una combinación distinta de (1, 2, 2).
Puede convertir su lista y en un conjunto para eliminar duplicados ...
import itertools
x = [1,1,1,2,2,2,3,3,3,4,4,5]
y = []
for x in itertools.permutations(x,3):
y.append(x)
print(set(y))
Y listo, ya está. :)
Lo que necesitas son permutaciones únicas en lugar de combinaciones:
y = list(set(itertools.permutations(x,3)))
Es decir, (1,2,2) y (2,1,2) se considerarán como la misma combinación y solo se devolverá una de ellas. Son, sin embargo, diferentes permutaciones. Utilice set()
para eliminar duplicados.
Si luego desea ordenar los elementos dentro de cada tupla y también ordenar la lista completa, puede hacerlo:
y = [tuple(sorted(q)) for q in y]
y.sort()
No hay necesidad de hacer bucle, las combinations
dan un generador.
x = [1,1,1,2,2,2,3,3,3,4,4,5]
y = list(set(itertools.combinations(x,3)))
set
se hará cargo de eso:
>>> a = [(1,2,2), (2,2,1), (1,2,2), (4,3,5), (3,3,5), (3,3,5), (3,4,5)]
>>> set(a)
set([(1, 2, 2), (2, 2, 1), (3, 4, 5), (3, 3, 5), (4, 3, 5)])
>>> list(set(a))
[(1, 2, 2), (2, 2, 1), (3, 4, 5), (3, 3, 5), (4, 3, 5)]
>>>
set
eliminará solo los duplicados exactos .