【问题标题】:How to overwrite python dictionary values?如何覆盖python字典值?
【发布时间】:2012-08-10 01:44:24
【问题描述】:

我的字典的简化:

my_dict = {
    'DOC': [
        [('k', 'v'), ('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3'), ('k4', 'v4')],
        [('k5', 'v5'), ('k', 'v'), ('k1', 'v1'), ('k6', 'v6')]
    ],
    'DIC': [
        [('k7', 'v7'), ('k3', 'v3'), ('k8', 'v8')],
        [('k5', 'v5'), ('k3', 'v3'), ('k1', 'v1'), ('k2', 'v2')],
        [('k4', 'v4'), ('k9', 'v9')]
    ],
    'INFRA': [
        [('k5', 'v5'), ('k3', 'v3'), ('k1', 'v1'), ('k2', 'v2')],
        [('k', 'v'), ('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3'), ('k4', 'v4')]
    ]
}

覆盖我的字典值:

for k, v in my_dict.items():
     my_dict[k] = map(lambda x: dict(x), my_dict[k])

返回...

my_dict 
{'DIC': [{'k3': 'v3', 'k7': 'v7', 'k8': 'v8'},
         {'k1': 'v1', 'k2': 'v2', 'k3': 'v3', 'k5': 'v5'},
         {'k4': 'v4', 'k9': 'v9'}],
 'DOC': [{'k': 'v', 'k1': 'v1', 'k2': 'v2', 'k3': 'v3', 'k4': 'v4'},
         {'k': 'v', 'k1': 'v1', 'k5': 'v5', 'k6': 'v6'}],
 'INFRA': [{'k1': 'v1', 'k2': 'v2', 'k3': 'v3', 'k5': 'v5'},
           {'k': 'v', 'k1': 'v1', 'k2': 'v2', 'k3': 'v3', 'k4': 'v4'}]}

当我按照相同的逻辑运行我的真实代码时,我得到了错误:

ValueError: 字典更新序列元素#0 的长度为 6; 2 是必需的

我尝试创建另一个字典来接收map(),但发生了同样的错误。有人可以帮助我吗?

【问题讨论】:

  • 您的代码对我来说运行良好。你能举一个导致ValueError的例子吗?
  • 很难在你看不到的代码中找到错误。 :(
  • 旁白:{k: map(dict,v) for k,v in my_dict.iteritems()} 稍微简单一些(2.7;.items() 在 3 中)。 lambda 是不必要的,即使您提取它,您也没有使用 v。
  • 将您的lambda 替换为在返回dict(x) 之前打印其参数的常规函数​​,并注意错误前打印的最后一件事。
  • @Jason Orendorff:问题似乎更有可能出现在我们看不到的数据中。

标签: python dictionary overwrite


【解决方案1】:

真实测试用例中的输入不符合您期望的结构。特别是,至少有一个元素是长度为 6 的序列,而不是所有的元组。例如,错误的输入可能看起来像:

{'DOC': [
    [('123456')],               # A string is a sequence, too
    [('123' '456')]             # Note the lack of a comma
    [('1','2','3','4','5','6')] # A tuple, but with 6 elements
    [['1','2','3','4','5','6']] # A list
]}

要解决此问题,请检查您的输入,例如:

for k, v in my_dict.items():
    for l in v:
        for subl in v:
            for tup in subl:
                if not len(tup) == 2:
                    raise ValueError('In %r: value is not a tuple(2), but %r'
                                     % (k, tup))

哦,顺便说一句,在设计数据结构时,遵循Zen of Python 通常是个好主意,其中包括:

平面比嵌套好。

【讨论】:

  • 我使用了建议的代码,但我的真实元组中没有 6 个元素的序列。
  • 你能简化你的真实元组,直到你得到一个你可以展示给我们的输入,但仍然失败?
  • @user1596206:您的一个元组中是否有可能缺少逗号?如果您忘记了逗号,('18', 'blue') 将变为单个六项字符串,因为 Python 隐式连接两个相邻的字符串。
  • @StevenRumbalski 很好的例子,大概就是这样。将其添加到此答案中,并为您的答案 +1。
【解决方案2】:

dict 构造函数需要一个包含 2 项子序列(列表或元组)的序列。至少有一个子序列包含两个以上的项目。

也许您缺少逗号(请参阅最后一项):

>>> dict([('1', 'red'),('2', 'blue'),('3' 'purple')]) # missing comma in last item
Traceback (most recent call last):
  File "<pyshell#166>", line 1, in <module>
    dict([('1', 'red'),('2', 'blue'),('3' 'purple')]) 
ValueError: dictionary update sequence element #2 has length 7; 2 is required

或者可能是单个项目而不是元组(再次,请参阅最后一项)

>>> dict([('1', 'red'),('2', 'blue'),('purple')]) # last "tuple" has one item
Traceback (most recent call last):
  File "<pyshell#167>", line 1, in <module>
    dict([('1', 'red'),('2', 'blue'),('purple')])
ValueError: dictionary update sequence element #2 has length 6; 2 is required

【讨论】:

  • 非常有趣的例子,但我检查了我的元组并没有注意到没有逗号或单个术语。我有 (u'vesti\xe1rio', None) 之类的东西,但它在 ipython 上运行。
  • @user1596206:您可能没有注意到问题,但问题确实存在。 Python 的错误信息说的是实话。尝试运行 phihag 为您编写的诊断程序。我认为它会让你的隐形错误可见。
  • @Steven Rumbalski:错误信息说的是真的。 phihag 提出的代码对我非常有用,返回 ValueError: In 'DOCENTE': value is not a tuple(2), but u'quadro'。所以,我可以检测到我之前发生的错误,它与覆盖 python 字典值无关。非常感谢您,如果问题没有继续,我们深表歉意。
【解决方案3】:

问题在于,在您的“真实代码”中,其中一个列表的第一个元素包含两个以上的元素 (6)。 dict 恰好需要两个才能将它们解释为 key, value。

这是一个生成您描述的错误的示例:

my_dict = {
    'DOC': [
        [('k', 'v', 'extra1', 'extra2', 'extra3', 'extra4'), ('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3'), ('k4', 'v4')],
        [('k5', 'v5'), ('k', 'v'), ('k1', 'v1'), ('k6', 'v6')]
    ],
    'DIC': [
        [('k7', 'v7'), ('k3', 'v3'), ('k8', 'v8')],
        [('k5', 'v5'), ('k3', 'v3'), ('k1', 'v1'), ('k2', 'v2')],
        [('k4', 'v4'), ('k9', 'v9')]
    ],
    'INFRA': [
        [('k5', 'v5'), ('k3', 'v3'), ('k1', 'v1'), ('k2', 'v2')],
        [('k', 'v'), ('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3'), ('k4', 'v4')]
    ]
}

这里有一个简单的方法来插入打印语句来查看问题元素:

for k, v in my_dict.items():

    # Print out the first element of each list,
    # because one of them has six elements when it should only have two.
    for l in my_dict[k]:
        print l[0]

    my_dict[k] = map(lambda x: dict(x), my_dict[k])

【讨论】:

    【解决方案4】:

    我认为您问题中的代码和数据没有问题。假设“真实”代码没有明显不同,您可以执行以下操作来找出导致错误发生的格式错误的数据:

    def test(x):
        print x
        return dict(x)
    
    for k, v in my_dict.items():
    #     my_dict[k] = map(lambda x: dict(x), my_dict[k])
         my_dict[k] = map(test, my_dict[k])
    

    【讨论】:

      【解决方案5】:

      这个比你的更简单的代码怎么样:

      temp_dict = {}
      for k in my_dict():
          temp_dict[k] = {}
          for t in my_dict[k]:
              temp_dict[k][t[0]] = t[1]
      my_dict = temp_dec
      del temp_dec
      

      【讨论】:

      • -1 这只会掩盖问题。错误的数据通常比错误更糟糕。
      猜你喜欢
      • 2021-01-14
      • 2011-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-03
      • 2018-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多