valor una repetidos repetido quitar palabra ocurrencias numeros listas lista identificar encontrar eliminar elementos duplicados contar buscar python list python-2.7

una - python quitar duplicados



encontrar duplicados en una lista de listas (7)

Estoy usando Python 2.7 y estoy tratando de quitar la duplicación de una lista de listas y combinar los valores de los duplicados.

En este momento tengo:

original_list = [[''a'', 1], [''b'', 1], [''a'', 1], [''b'', 1], [''b'', 2], [''c'', 2], [''b'', 3]]

Quiero hacer coincidir el primer elemento de cada lista anidada y luego agregar los valores del segundo elemento. Quiero terminar con esto (el orden de la lista final no importa):

ideal_output = [[''a'', 2], [''b'', 7], [''c'', 2]]

Hasta ahora tengo un código que me encontrará los valores duplicados en función del primer elemento de cada lista anidada:

for item in original_list: matches = -1 for x in original_list: if (item[0] == x[0]): matches += 1 if matches >= 1: if item[0] not in duplicates_list: duplicates_list.append(item[0])

Desde aquí necesito buscar todos los elementos de la lista de duplicados que están en la lista original y sumar los valores, pero no estoy seguro de cuál es la mejor manera de hacerlo.


SOLUCIÓN

Usar collections.Counter . collections.Counter :

from collections import Counter original_list = [[''a'', 1], [''b'', 1], [''a'', 1], [''b'', 1], [''b'', 2], [''c'', 2], [''b'', 3]] result = Counter() for k, v in original_list: result.update({k:v}) map(list, result.items()) # [[''a'', 2], [''c'', 2], [''b'', 7]]

RECOMENDACIONES

Entonces, muchas respuestas, puntos de vista y votaciones ascendentes. Incluso obtuve mi primera Nice answer de la nada (en los últimos 2 días hice un montón de respuestas por valor de más investigación y esfuerzos). En vista de esto, decidí hacer al menos un rendimiento de soluciones de investigación y prueba con un simple script escrito desde cero. No incluya el código directamente en la respuesta por el tamaño.

Cada función lleva el nombre de su autor y se puede encontrar fácilmente en cuestión. La solución de itertools.groupby ahora es igual a una de Mark Reed y se evalúa en su forma original, thefourtheye2 establece para la solución basada en itertools.groupby .

Cada uno se probó varias veces (muestras), cada muestra a su vez invocó varias iteraciones de funciones. Evalué min, max y desviación estándar para muestras veces.

Aquí vamos, haciendo una prueba de sondeo por 10 veces.

testing: thefourtheye, kroolik2, void, kroolik, alko, reed, visser 10 samples 10 iterations each author min avg max stddev reed 0.00000 0.00000 0.00000 0.00000 visser 0.00000 0.00150 0.01500 0.00450 thefourtheye 0.00000 0.00160 0.01600 0.00480 thefourtheye2 0.00000 0.00310 0.01600 0.00620 alko 0.00000 0.00630 0.01600 0.00772 void 0.01500 0.01540 0.01600 0.00049 kroolik2 0.04700 0.06430 0.07800 0.00831 kroolik 0.32800 0.34380 0.37500 0.01716

Observe las dos filas inferiores: en este punto, las soluciones de kroolik se descalificaron, ya que con ellas se realizarán iteraciones razonables de muestras * durante horas. Aquí van las pruebas finales. Yo manualmente agregué el número de votos a favor de ouptut:

testing: thefourtheye, kroolik2, void, kroolik, alko, reed, visser 100 samples 1000 iterations each author upvotes min avg max stddev reed [20] 0.06200 0.08174 0.15600 0.01841 thefourtheye [5] 0.06200 0.09971 0.20300 0.01911 visser [6] 0.10900 0.12392 0.23500 0.02263 thefourtheye2 0.25000 0.29674 0.89000 0.07183 alko [11] 0.56200 0.62309 1.04700 0.08438 void [3] 1.50000 1.65480 2.39100 0.18721 kroolik [14] [DSQ]


Muchas buenas respuestas, pero todas usan bastante más código del que usaría para esto, así que aquí está mi opinión, por lo que vale:

totals = {} for k,v in original_list: totals[k] = totals.get(k,0) + v # totals = {''a'': 2, ''c'': 2, ''b'': 7}

Una vez que tenga un dict como ese, a partir de cualquiera de estas respuestas, puede usar items para obtener una lista de tuplas:

totals.items() # => [(''a'', 2), (''c'', 2), (''b'', 7)]

Y una list mapas a través de las tuplas para obtener una lista de listas:

map(list, totals.items()) # => [[''a'', 2], [''c'', 2], [''b'', 7]]

Y ordena si los quieres en orden:

sorted(map(list, totals.items())) # => [[''a'', 2], [''b'', 7], [''c'', 2]]


Puede ser que puedas probar esto también,

>>> x = [[1,1],[2,2],[1,1],[2,2],[3,3],[4,4],[4,4]] >>> z = [] >>> for i in x: >>> if i not in z: >>> z.append(i) >>> >>> z [[1, 1], [2, 2], [3, 3], [4, 4]]


Puede usar collections.defaultdict :

original_list = [[''a'', 1], [''b'', 1], [''a'', 1], [''b'', 1], [''b'', 2], [''c'', 2], [''b'', 3]] import collections data = collections.defaultdict(list) for item in original_list: data[item[0]].append(item[1]) output = {key: sum(values) for key, values in data.items()} print output # gives: {''a'': 2, ''c'': 2, ''b'': 7}


Sé que es feo, pero me estaba divirtiendo al tratar de implementarlo en un trazador de líneas 1:

map(list, set(([(x[0], sum([i[1] for i in original_list if i[0]==x[0]])) for x in original_list])))

salida:

[[''a'', 2], [''b'', 7], [''c'', 2]]


Si la orden no importa, puede usar esto

original_list = [[''a'', 1], [''b'', 1], [''a'', 1], [''b'', 1], [''b'', 2], [''c'', 2], [''b'', 3]] myDict = {} for first, second in original_list: myDict[first] = myDict.get(first, 0) + second result = [[key, value] for key, value in myDict.items()] print result

O puede usar groupby y el código se convierte en un oneliner

original_list = [[''a'', 1], [''b'', 1], [''a'', 1], [''b'', 1], [''b'', 2], [''c'', 2], [''b'', 3]] from itertools import groupby print [[key, sum(item[1] for item in list(group))] for key, group in groupby(sorted(original_list), lambda x:x[0])]

Salida

[[''a'', 2], [''b'', 7], [''c'', 2]]


>>> from collections import Counter >>> lst = [[''a'', 1], [''b'', 1], [''a'', 1], [''b'', 1], [''b'', 2], [''c'', 2], [''b'', 3]] >>> c = Counter(x for x, c in lst for _ in xrange(c)) Counter({''b'': 7, ''a'': 2, ''c'': 2}) >>> map(list, c.iteritems()) [[''a'', 2], [''c'', 2], [''b'', 7]]

O alternativamente, sin repetir cada elemento (a, b) b veces (@hcwhsa):

>>> from collections import Counter >>> lst = [[''a'', 1], [''b'', 1], [''a'', 1], [''b'', 1], [''b'', 2], [''c'', 2], [''b'', 3]] >>> c = sum((Counter(**{k:v}) for k, v in lst), Counter()) Counter({''b'': 7, ''a'': 2, ''c'': 2}) >>> map(list, c.iteritems()) [[''a'', 2], [''c'', 2], [''b'', 7]]