51 votes

Comment obtenir efficacement la moyenne des éléments dans deux listes de listes en Python

J'ai deux listes comme suit.

 mylist1 = [["lemon", 0.1], ["egg", 0.1], ["muffin", 0.3], ["chocolate", 0.5]]
mylist2 = [["chocolate", 0.5], ["milk", 0.2], ["carrot", 0.8], ["egg", 0.8]]

Je veux obtenir la moyenne des éléments communs dans les deux listes comme suit.

 myoutput = [["chocolate", 0.5], ["egg", 0.45]]

Mon code actuel est le suivant

 for item1 in mylist1:
    for item2 in mylist2:
        if item1[0] == item2[0]:
             print(np.mean([item1[1], item2[1]]))

Cependant, comme il y a deux for boucles ( O(n^2) complexité) ce qui est très inefficace pour les très longues listes. Je me demande s'il existe un moyen plus standard/efficace de le faire en Python.

37voto

Adam.Er8 Points 10581

Vous pouvez le faire en O(n) (passage unique sur chaque liste) en convertissant 1 en dict, puis par élément de la 2ème liste accéder à ce dict (en O(1)), comme ceci :

 mylist1 = [["lemon", 0.1], ["egg", 0.1], ["muffin", 0.3], ["chocolate", 0.5]]
mylist2 = [["chocolate", 0.5], ["milk", 0.2], ["carrot", 0.8], ["egg", 0.8]]

l1_as_dict = dict(mylist1)

myoutput = []
for item,price2 in mylist2:
    if item in l1_as_dict:
        price1 = l1_as_dict[item]
        myoutput.append([item, (price1+price2)/2])

print(myoutput)

Sortir:

 [['chocolate', 0.5], ['egg', 0.45]]

17voto

AChampion Points 6537

Une O(n) qui fera la moyenne de tous les éléments. Construisez un dictionnaire avec une liste de valeurs, puis faites la moyenne de ce dictionnaire par la suite :

 In []:
d = {}
for lst in (mylist1, mylist2):
    for i, v in lst:
        d.setdefault(i, []).append(v)   # alternative use collections.defaultdict

[(k, sum(v)/len(v)) for k, v in d.items()]

Out[]:
[('lemon', 0.1), ('egg', 0.45), ('muffin', 0.3), ('chocolate', 0.5), ('milk', 0.2), ('carrot', 0.8)]

Ensuite, si vous voulez juste les communs, vous pouvez ajouter une garde :

 In []:
[(k, sum(v)/len(v)) for k, v in d.items() if len(v) > 1]

Out[]:
[('egg', 0.45), ('chocolate', 0.5)]

Cela s'étend à n'importe quel nombre de listes et ne fait aucune hypothèse sur le nombre d'éléments communs.

7voto

azro Points 11463

Pour manipuler facilement vos valeurs, je vous suggère d'utiliser un dict , de trouver les clés communes et de calculer la moyenne :

 mylist1 = [["lemon", 0.1], ["egg", 0.1], ["muffin", 0.3], ["chocolate", 0.5]]
mylist2 = [["chocolate", 0.5], ["milk", 0.2], ["carrot", 0.8], ["egg", 0.8]]

recipe_1 = dict(mylist1)  # {'lemon': 0.1, 'egg': 0.1, 'muffin': 0.3, 'chocolate': 0.5}
recipe_2 = dict(mylist2)  # {'chocolate': 0.5, 'milk': 0.2, 'carrot': 0.8, 'egg': 0.8}

common_keys = recipe_1.keys() & recipe_2.keys()  # {'chocolate', 'egg'}

myoutput = [[item, np.mean((recipe_1[item], recipe_2[item]))] for item in common_keys]
myoutput = [[item, (recipe_1[item] + recipe_2[item]) / 2] for item in common_keys]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X