J'ai une liste de tuples:

[(0.0, 287999.70000000007),
(1.0, 161123.23000000001),
(2.0, 93724.140000000014),
(3.0, 60347.309999999983),
(4.0, 55687.239999999998),
(5.0, 29501.349999999999),
(6.0, 14993.920000000002),
(7.0, 14941.970000000001),
(8.0, 13066.229999999998),
(9.0, 10101.040000000001),
(10.0, 4151.6900000000005),
(11.0, 2998.8899999999999),
(12.0, 1548.9300000000001),
(15.0, 1595.54),
(16.0, 1435.98),
(17.0, 1383.01)]

Comme on peut le voir, il manque des index (13 et 14). Je veux remplir les index manquants avec des zéros:

[(0.0, 287999.70000000007),
(1.0, 161123.23000000001),
(2.0, 93724.140000000014),
(3.0, 60347.309999999983),
(4.0, 55687.239999999998),
(5.0, 29501.349999999999),
(6.0, 14993.920000000002),
(7.0, 14941.970000000001),
(8.0, 13066.229999999998),
(9.0, 10101.040000000001),
(10.0, 4151.6900000000005),
(11.0, 2998.8899999999999),
(12.0, 1548.9300000000001),
(13.0, 0),
(14.0, 0),
(15.0, 1595.54),
(16.0, 1435.98),
(17.0, 1383.01)]

J'ai fait quelque chose de laid avec for loop (je ne l'ai pas ajouté car je ne pense pas que cela contribuera à quoi que ce soit ...), mais je me demandais s'il y avait une manière élégante de résoudre ce problème? (peut-être 3-4 lignes avec list comprehension).

1
Binyamin Even 7 mars 2016 à 12:41

3 réponses

Meilleure réponse

Une simple boucle for est probablement plus facile qu'une compréhension de liste:

data = [(0.0, 287999.70000000007),
(1.0, 161123.23000000001),
(2.0, 93724.140000000014),
(3.0, 60347.309999999983),
(4.0, 55687.239999999998),
(5.0, 29501.349999999999),
(6.0, 14993.920000000002),
(7.0, 14941.970000000001),
(8.0, 13066.229999999998),
(9.0, 10101.040000000001),
(10.0, 4151.6900000000005),
(11.0, 2998.8899999999999),
(12.0, 1548.9300000000001),
(15.0, 1595.54),
(16.0, 1435.98),
(17.0, 1383.01)]

result = []
last = 0.0
for d in data:
    while last < d[0]:
        result.append((last, 0))
        last += 1
    result.append(d)
    last = d[0]+1

Légèrement plus court (et comprenant une liste de compréhension):

result, last = [], 0.0
for d in data:
    result.extend((r,0) for r in range(int(last), int(d[0])))
    result.append(d)
    last = d[0]+1
2
Duncan 7 mars 2016 à 09:57

Vous pouvez le faire en convertissant vos données en dictionnaire, puis en récupérant chaque index avec dict.get() afin que vous puissiez par défaut la valeur à 0.

Version compacte:

def fill_missing_with_zero(collection, fill=0.0):
    d = dict(collection)
    return [(key, d.get(key, fill)) for key in [float(i) for i in range(int(max(d))+1)]]

Pour plus de détails, comme suit:

def fill_missing_with_zero(collection, fill=0.0):
    d = dict(collection)
    highest_index = int(max(d.keys()))
    result = []
    for i in range(highest_index+1):
        key = float(i)  # because your "keys" are floats
        result.append((key, d.get(key, fill)))
    return result

Exemple:

>>> fill_missing_with_zero(collection))
[(0.0, 287999.70000000007),
 (1.0, 161123.23),
 (2.0, 93724.14000000001),
 (3.0, 60347.30999999998),
 (4.0, 55687.24),
 (5.0, 29501.35),
 (6.0, 14993.920000000002),
 (7.0, 14941.970000000001),
 (8.0, 13066.229999999998),
 (9.0, 10101.04),
 (10.0, 4151.6900000000005),
 (11.0, 2998.89),
 (12.0, 1548.93),
 (13.0, 0.0),
 (14.0, 0.0),
 (15.0, 1595.54),
 (16.0, 1435.98),
 (17.0, 1383.01)]
0
Inbar Rose 7 mars 2016 à 10:02

J'ai légèrement modifié votre entrée pour utiliser des valeurs entières.

Présumer l'entrée est en ordre. Je travaille d'abord sur la clé la plus élevée de la liste. top = in_list [-1] [0]

Convertissez ensuite l'entrée en dict.

Cela signifie que je peux utiliser get (clé [, par défaut]) pour retourner un zéro si la clé n'existe pas.

Utilisez ensuite une compréhension de liste avec plage pour parcourir les entiers possibles. Doit être top + 1 car la plage renvoie le nombre d'éléments, et donc à partir de zéro, en a besoin d'un de plus.

list=[(0, 287999.70000000007),
(1, 161123.23000000001),
(2, 93724.140000000014),
(3, 60347.309999999983),
(4, 55687.239999999998),
(5, 29501.349999999999),
(6, 14993.920000000002),
(7, 14941.970000000001),
(8, 13066.229999999998),
(9, 1010140000000001),
(10, 4151.6900000000005),
(11, 2998.8899999999999),
(12, 1548.9300000000001),
(15, 1595.54),
(16, 1435.98),
(17, 1383.01)]

top=in_list[-1][0]
in_dict=dict(in_list)
out_list=[ (i,in_dict.get(i,0)) for i in range(top+1)]
print(out_list)
0
Tim Bray 7 mars 2016 à 10:00