Tengo una lista de tuplas (primer elemento, por ejemplo, la cadena3 puede repetirse): [('cadena1', 10), ('cadena2', 200), ('cadena3', 50), ('cadena3', 45)] . Necesito devolver una lista que contenga 'string' (primeros elementos de tuplas) ordenados según la suma de sus pares y debería incluirlos en una lista solo si la suma es inferior a un cierto umbral.

Entonces, el resultado si el umbral es 100 debería ser como ['string3', 'string1']

-1
Yodo 3 oct. 2019 a las 07:06

4 respuestas

La mejor respuesta
def sort_thresh(ls,threshold = 100):
    a = {}
    for key,val in ls:
        a[key] = a.get(key,0) + val
    a = {key:val for key,val in a.items() if val<=threshold}
    return sorted(a,key=a.get,reverse=True)

sort_thresh([('string1',10), ('string2', 200), ('string3', 50), ('string3',45)])
Out[89]: ['string3', 'string1']
1
Onyambu 3 oct. 2019 a las 05:30

Una solución fácil sería sumar con un collections.Counter, luego ordena en reversa y solo guarda las claves:

from collections import Counter

lst = [('string1',10), ('string2', 200), ('string3', 50), ('string3',45)]

counts = Counter()
for string, number in lst:
    counts[string] += number

print(sorted((k for k, v in counts.items() if v < 100), reverse=True))
# ['string3', 'string1']
0
RoadRunner 3 oct. 2019 a las 05:18

Si la memoria no es una preocupación, puede crear un diccionario que almacenará la suma de segundos elementos para cada clave única. Pruebe el siguiente código

lst = [('string1',10), ('string2', 200), ('string3', 50), ('string3',45)]
d= dict()
threshold = 100
for tup in lst:
    if tup[0] not in d:
        d[tup[0]] = tup[1]
    else: d[tup[0]] += tup[1]
item_pairs = sorted(d.items(), key=lambda x: x[1], reverse=True)
lst = [tup[0] for tup in item_pairs if tup[1] < threshold]
print lst
0
yabhishek 3 oct. 2019 a las 04:17

Otra solución usando pandas

import pandas as pd
l = [('string1',10), ('string2', 200), ('string3', 50), ('string3',45)]
df = pd.DataFrame(l, columns=["String", "Value"])
df = df.groupby(["String"], as_index=False)["Value"].sum()
df=df[df["Value"]<100]
df=df.sort_values("Value", ascending=False)
print(df["String"].tolist())
2
san 3 oct. 2019 a las 04:55
58212157