Проблема со словарной итерацией в python - PullRequest
2 голосов
/ 02 апреля 2020

Я новичок в python, поэтому, возможно, мою проблему легко решить. У меня есть словарь, организованный следующим образом: my_dict = {'x': (1.1, 3.4), 'y': (4.3, 7.5), 'z': (7.3, 9.5)}. Я хотел бы уменьшить каждое значение на одно и то же число, поэтому я пытаюсь сделать следующее:

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

При использовании этого кода я получаю эту ошибку:

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

Таким образом, кажется, что «для a, b в v» l oop пытается перебрать float, что невозможно. Таким образом, я попытался напечатать my_dict.items () и k, v в для l oop, чтобы увидеть, что такое итерация для l oop, и вот что я получаю:

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)

Я вижу две странные вещи: - Я ожидал, что команда «print k, v» напечатает каждый ключ, пару значений, но я получаю только ключ y с его значением - Посмотрев на my_dict.items (), мне кажется, что v это не число с плавающей точкой, а кортеж, содержащий два числа с плавающей точкой. Так почему же я получаю объект float не повторяемая ошибка?

Любая помощь приветствуется. Опять же, я прошу прощения, если это глупый вопрос, но я только начал использовать python, и я застрял с этим.

Спасибо!

Ответы [ 7 ]

2 голосов
/ 02 апреля 2020

Здесь вы можете использовать понимание в словах

>>> {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)}
1 голос
/ 02 апреля 2020

Я бы предложил использовать словарное понимание:

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)}

Если вы хотите сохранить l oop, вам придется удалить вложенный for-l oop, поскольку он не нужен для расширить кортежи. Вы можете просто написать это так:

for k,(a,b) in my_dict.items():
    my_dict[k] = (a*0.3, b*0.3)
1 голос
/ 02 апреля 2020

вы можете распаковать ваши значения dict:

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

или вы можете использовать:

dict(map(lambda x: (x[0], (x[1][0]*0.3, x[1][1]*0.3)),   my_dict.items()))
1 голос
/ 02 апреля 2020

Вам не нужно перебирать кортеж, а просто назначать его переменным:

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

и немного более приятное решение:

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

1 голос
/ 02 апреля 2020

Проблема здесь в том, что:

for a, b in v

Вы пытаетесь перебрать один кортеж, что на самом деле не имеет смысла, так как вы уже распаковываете его .

Обратите внимание, что все, что вам нужно, - это распаковать его значения следующим образом:

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

Теперь a и b содержат оба значения кортежа соответственно. Таким образом, единственная проблема в вашем коде заключается в том, что внутреннее for.

Итак, ясно, что это не имеет смысла, но почему возникает ошибка?

Это связано с тем, что Python ожидает, что v будет итерируемым из итераций, поскольку вы пытаетесь распаковать каждую итерацию в k и v. В этом случае, когда вы перебираете v, первым возвращаемым элементом является его первый float, который не может быть распакован.

Обратите внимание, что если бы вместо этого мы перебрали список, содержащий кортеж, ваш подход сработал бы:

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)

Хотя, как уже упоминалось, это не имеет смысла, учитывая, что вы можете просто распаковать напрямую их:

for k,v in my_dict.items():
    a, b = v
    a = a * 0.3
    b = b * 0.3 
    my_dict[k] = (a, b)
1 голос
/ 02 апреля 2020

Строка кода for a, b in v не имеет смысла, потому что есть только одно значение v, которое является вашим кортежем. Вы уже просматриваете элементы словаря в вашем внешнем l oop. Попробуйте следующее:

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 голос
/ 02 апреля 2020

@ CoryKramer уже прибил Pythoni c способ сделать это. Сосредоточиться на вашем коде ...

Ваш внутренний "l oop" - неправильная техника. Вам не нужно повторять через кортеж - для этого требуется один элемент за раз, а вам нужно два сразу. Скорее, вам нужно «распаковать» кортеж.

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)
...