【问题标题】:Problem with dictionary iteration in pythonpython中字典迭代的问题
【发布时间】:2020-07-14 18:55:38
【问题描述】:

我是 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

所以看起来“for a, b in v”循环试图迭代浮点数,这是不可能的。 因此,我尝试在 for 循环中打印 my_dict.items() 和 k,v,以便查看 for 循环遍历的内容是什么,这就是我得到的:

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)

我可以看到两件奇怪的事情: - 我期待“打印 k,v”命令打印每个键,值对,但我只得到 y 键及其值 - 通过查看 my_dict.items(),在我看来 v 不是浮点数,而是包含两个浮点数的元组。那么为什么我会得到 float object is not iterable 错误呢?

非常感谢任何帮助。 再次,如果这是一个愚蠢的问题,我很抱歉,但我刚开始使用 python,我被这个问题困住了。

谢谢!

【问题讨论】:

  • 你的意思只是a, b = v 解包元组

标签: python dictionary tuples iteration typeerror


【解决方案1】:

你可以在这里使用字典理解

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

【讨论】:

  • 这听起来很棒!谢谢!如果我想制作 a * 0.3 和 b * 0.5 怎么办?
  • 在这种情况下,使用(v[0]*0.3, v[1]*0.5)
  • 你也可以用更一般的东西来做,比如(i * c for i, c in zip(v, (0.3, 0.5)) for k, v ...)
【解决方案2】:

@CoryKramer 已经确定了执行此操作的 Pythonic 方式。 专注于您的代码...

你的内在“循环”不是正确的技术。 您不需要迭代 元组——一次需要一个元素,而您一次需要两个元素。相反,您需要“解包”元组。

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)

【讨论】:

  • 可以在my_dict.items()中使用for k, (a, b): 并保存一行代码)
  • 我知道——我正在尽我所能接近 OP 的代码。
【解决方案3】:

代码行for a, b in v 没有意义,因为只有一个值v 是您的元组。您已经在外循环中遍历字典中的项目。请尝试以下操作:

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

【讨论】:

    【解决方案4】:

    你可以解压你的字典值:

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

    【讨论】:

      【解决方案5】:

      您不必遍历元组,只需将其分配给变量:

      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
      
      

      【讨论】:

        【解决方案6】:

        这里的问题在于:

        for a, b in v
        

        您正在尝试遍历单个元组,这实际上没有任何意义,因为 您已经在解包它

        请注意,您只需将其值解压缩为:

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

        现在ab 分别包含两个元组值。所以你的代码中唯一的问题是内部for

        那么明明没有意义,但是为什么会出现错误呢?

        这是因为 Python 期望 v 是可迭代对象的可迭代对象,因为您试图将每个可迭代对象解压缩为 kv。在这种情况下,当您迭代 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)
        

        【讨论】:

          【解决方案7】:

          我建议使用字典理解:

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

          如果要保留循环,则必须删除嵌套的 for 循环,因为不需要扩展元组。你可以这样写:

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

          【讨论】:

            猜你喜欢
            • 2021-07-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-12-03
            • 1970-01-01
            相关资源
            最近更新 更多