Jestem nowy w Pythonie, więc może mój problem jest łatwy do rozwiązania. Mam słownik zorganizowany w następujący sposób: my_dict = {'x': (1.1, 3.4), 'y': (4.3, 7.5), 'z': (7.3, 9.5)}. Chciałbym zmniejszyć każdą wartość o tę samą liczbę, więc próbuję to zrobić:

for k,v in my_dict.items():
    for a, b in v:
        a = a * 0.3
        b = b * 0.3 
        my_dict[k] = (a, b)
return my_dict

Podczas korzystania z tego kodu otrzymuję następujący błąd:

for a, b in v:
TypeError: 'float' object is not iterable

Wygląda więc na to, że pętla „for a, b in v” próbuje wykonać iterację przez zmiennoprzecinkę, co nie jest możliwe. W związku z tym próbowałem wydrukować my_dict.items () i k, v w pętli for, aby zobaczyć, przez co iteruje pętla for, i oto, co otrzymuję:

for k,v in my_dict.items():
    print my_dict.items()
    print k,v

[('x', (1.1, 3.4)), ('y', (4.3, 7.5)), ('z', (7.3, 9.5))]
y (4.3, 7.5)

Widzę dwie dziwne rzeczy: - Spodziewałem się, że polecenie „print k, v” wydrukuje każdy klucz, parę wartości, ale otrzymuję tylko klucz y z jego wartością - Patrząc na my_dict.items (), wydaje mi się, że v nie jest liczbą zmiennoprzecinkową, ale krotką zawierającą dwie liczby zmiennoprzecinkowe. Więc dlaczego dostaję, że obiekt pływający nie jest iterowalny błąd?

Każda pomoc jest mile widziana. Ponownie, przepraszam, jeśli to głupie pytanie, ale właśnie zacząłem używać Pythona i utknąłem z tym.

Dziękuję Ci!

2
ginopino 2 kwiecień 2020, 20:41

7 odpowiedzi

Najlepsza odpowiedź

Możesz tutaj użyć dyktowania ze zrozumieniem

>>> {k: tuple(i * 0.3 for i in v) for k, v in my_dict.items()}
{'x': (0.33, 1.02), 'y': (1.2899999999999998, 2.25), 'z': (2.19, 2.85)}
2
Cory Kramer 2 kwiecień 2020, 17:43

@CoryKramer już przyjął sposób na to w Pythonie. Aby skupić się na Twoim kodzie ...

Twoja wewnętrzna „pętla” nie jest właściwą techniką. Nie musisz iterować przez krotkę - zajmuje to jeden element na raz, a chcesz mieć dwa na raz. Zamiast tego musisz „rozpakować” krotkę.

my_dict = {'x': (1.1, 3.4), 'y': (4.3, 7.5), 'z': (7.3, 9.5)}

for k,v in my_dict.items():
    print("dict:", k, v)
    a, b = v
    print("val:", a, b)
    a = a * 0.3
    b = b * 0.3
    my_dict[k] = (a, b)
1
Prune 2 kwiecień 2020, 17:48

Wiersz kodu for a, b in v nie ma sensu, ponieważ jest tylko jedna wartość v, która jest Twoją krotką. Już przeglądasz elementy w słowniku w zewnętrznej pętli. Spróbuj wykonać następujące czynności:

for k,v in my_dict.items():
    a, b = v
    a = a * 0.3
    b = b * 0.3 
    my_dict[k] = (a, b)
return my_dict
1
ericstevens26101 2 kwiecień 2020, 17:50

Możesz rozpakować swoje dict wartości:

for k, (a, b) in my_dict.items():
    a *= 0.3
    b *= 0.3 
    my_dict[k] = (a, b)

Lub możesz użyć:

dict(map(lambda x: (x[0], (x[1][0]*0.3, x[1][1]*0.3)),   my_dict.items()))
1
kederrac 2 kwiecień 2020, 17:58

Nie musisz iterować po krotce, ale po prostu przypisz ją do zmiennych:

for k,v in my_dict.items():
    a, b = v
    a = a * 0.3
    b = b * 0.3 
    my_dict[k] = (a, b)
return my_dict

I trochę ładniejsze rozwiązanie:

for k,v in my_dict.items():
    my_dict[k] = tuple([0.3*x for x in v])
return my_dict

1
Gabip 2 kwiecień 2020, 18:08

Problem polega na tym, że wykonując:

for a, b in v

Próbujesz wykonać iterację po jednej krotce, co nie ma sensu, ponieważ już ją rozpakowujesz .

Zauważ, że wszystko, czego potrzebujesz, to rozpakować jego wartości jako:

k,v = next(iter(my_dict.items()))
a, b = v

Teraz a i b zawierają odpowiednio obie wartości krotki. Więc jedynym problemem w Twoim kodzie jest to, że wewnętrzne for.

Jest więc jasne, że nie ma to sensu, ale dlaczego występuje błąd?

Dzieje się tak, ponieważ Python oczekuje, że v będzie iterowalnym elementem iterowalnym, ponieważ próbujesz rozpakować każdą iterację do k i v. W tym przypadku, kiedy iterujesz po v, pierwszym zwracanym elementem jest jego pierwszy float, którego nie można rozpakować.

Zauważ, że gdybyśmy zamiast tego przejrzeli listę zawierającą krotkę, Twoje podejście zadziałałoby:

for k,v in my_dict.items():
    for a, b in [v]:
        a = a * 0.3
        b = b * 0.3 
        my_dict[k] = (a, b)

Chociaż, jak wspomniano, nie ma to sensu, biorąc pod uwagę, że można je po prostu rozpakować:

for k,v in my_dict.items():
    a, b = v
    a = a * 0.3
    b = b * 0.3 
    my_dict[k] = (a, b)
1
yatu 2 kwiecień 2020, 18:11

Sugerowałbym użycie rozumienia słownikowego:

my_dict = {'x': (1.1, 3.4), 'y': (4.3, 7.5), 'z': (7.3, 9.5)}

f = 0.3
my_dict = {k:(a*f,b*f) for k,(a,b) in my_dict.items()}

print(my_dict)  # {'x': (0.33, 1.02), 'y': (1.2899999999999998, 2.25), 'z': (2.19, 2.85)}

Jeśli chcesz zachować pętlę, będziesz musiał usunąć zagnieżdżoną pętlę for, ponieważ nie jest ona potrzebna do rozwijania krotek. Możesz po prostu napisać to w ten sposób:

for k,(a,b) in my_dict.items():
    my_dict[k] = (a*0.3, b*0.3)
1
Alain T. 2 kwiecień 2020, 19:43