2012-03-19 3 views
1

Je liste imbriquée de la forme suivante:Liste Nested - Cordes FLOTTER

my_list = [['Some1', '2', '3.6', '4.5', 'GB2', '6'], 
      ['Some2', '3.9', '4', '5', 'HG5', '7.3'], 
      ['Some3', '4', '5', '6.1', 'H2D', '8.9']] 

Chaque élément de chaque sous-liste est une chaîne, mais je voudrais tourner toutes les chaînes purement numériques en flotteurs.

J'essayer le code suivant:

for row in my_list: 
    for k, item in enumerate(row): 
     if k in (1, 2, 3, 5): 
      item = float(item) 

Malheureusement, la liste imbriquée reste inchangée. Je suis sûr que je fais une erreur simple, mais je ne peux pas le voir. Toute aide (et contexte) serait appréciée.

Répondre

4

La réaffectation du nom item ne changera jamais la liste. Essayez ceci à la place:

for row in my_list: 
    for k in (1, 2, 3, 5): 
     row[k] = float(row[k]) 

Notez que les noms Python ne sont que des étiquettes attachées à certains objets. Une ligne comme

item = float(item) 

calcule float(item) et lier ensuite le nom item à l'objet retourné. Cela ne fait rien à l'objet item pointé vers avant. De plus, dans ce cas, il est impossible de muter ce dernier objet - les chaînes sont immuables.

+0

ce qui serait considéré comme plus Pythonic dans ce cas, une boucle ou une compréhension de la liste création my_list2 comme DSM suggère? L'un ou l'autre est-il préféré? Mes listes actuelles peuvent atteindre 100 000 + lignes. – donopj2

+0

@PatrickD: Les deux réponses font des choses différentes. Le code dans ma réponse mute la liste originale en place. Le code dans la réponse de DSM crée une nouvelle liste. Une autre différence est que le code dans ma réponse code les colonnes à convertir, et expira si une valeur ne peut pas être convertie. Le code dans la réponse de DSM essaie de convertir chaque élément et utilise la valeur à virgule flottante au lieu de la valeur d'origine si la conversion réussit. Le code dans cette réponse est plus rapide et consomme moins de mémoire, à condition que vous vouliez ces sémantiques. –

4

Vous n'affectez pas la liste d'origine; vous faites simplement un flottement à partir de certains éléments et vous donnez le nom "item" à son tour. Vous pouvez utiliser quelque chose comme

row[k] = float(item) 

mais je ferais probablement quelque chose comme

def floatify(x): 
    try: 
     return float(x) 
    except ValueError: 
     return x 

my_list2 = [[floatify(x) for x in row] for row in my_list] 
0

Vous aurez besoin de réaffecter des éléments de ligne à la nouvelle valeur calculée par exemple

row[k] = float(item) 
1
for index1, row in enumerate(my_list): 
    for index2, item in enumerate(row): 
     try: 
      my_list[index1][index2] = (float(item)) 
     except ValueError: 
      pass 
print my_list 
[['Some1', 2.0, 3.6000000000000001, 4.5, 'GB2', 6.0], 
['Some2', 3.8999999999999999, 4.0, 5.0, 'HG5', 7.2999999999999998], 
['Some3', 4.0, 5.0, 6.0999999999999996, 'H2D', 8.9000000000000004]]