0

可能重复:
如果字典中的键重复,如何引发错误

我最近正在生成包含数十万个键的庞大字典(这样通过查看它们来发现错误是不可行的)。它们在语法上是正确的,但在某个地方存在错误。它归结为“重复键”:

{'a':1, ..., 'a':2}

这段代码编译得很好,我无法弄清楚为什么akey 的值2与我预期的一样1。现在问题很明显了。

问题是我将来如何防止这种情况发生。我认为这在 python 中是不可能的。我用了

grep "'.*'[ ]*:" myfile.py | sort | uniq -c | grep -v 1

这不是防弹的。任何其他想法(在 python 中,这个 grep 只是为了说明我尝试过的内容)?

编辑:我不想要重复的键,只需要发现这种情况并手动编辑数据

4

4 回答 4

0

您是否正在生成一个包含巨大字典的 Python 文件?就像是:

print "{"
for lines in file:
    key, _, value = lines.partition(" ")
    print "    '%s': '%s',"
print "}"

如果是这样,你可以做很多事情来防止这种情况,因为你不能轻易地覆盖 builtin 的构造dict

相反,我建议您在构造字典字符串时验证数据。您还可以生成不同的语法:

dict(a = '1', a = '2')

SyntaxError..如果密钥重复,它将生成一个。但是,这些并不完全等效,因为字典键比关键字参数灵活得多(例如{123: '...'} is valid, butdict(123 = '...')` 是错误的)

您可以生成如下函数调用:

uniq_dict([('a', '...'), ('a', '...')])

然后包括函数定义:

def uniq_dict(values):
    thedict = {}

    for k, v in values:
        if k in thedict:
            raise ValueError("Duplicate key %s" % k)
        thedict[k] = v

     return thedict
于 2012-10-10T11:26:32.393 回答
0

如果您需要每个键有多个值,则可以使用 defaultdict 将值存储在列表中。

>>> from collections import defaultdict
>>> data_dict = defaultdict(list)
>>> data_dict['key'].append('value')
>>> data_dict
defaultdict(<type 'list'>, {'key': ['value']})
>>> data_dict['key'].append('second_value')
>>> data_dict
defaultdict(<type 'list'>, {'key': ['value', 'second_value']})
于 2012-10-10T10:09:32.403 回答
0

您没有确切地说或显示您是如何生成出现重复键的字典显示的。但这就是问题所在。

{'a':1, ..., 'a':2}我建议您使用这种形式,而不是使用类似构建字典的东西:dict([['a', 1], ..., ['a', 2]])它将从提供的[key, value]对列表中创建一个。dict()这种方法将允许您在将其传递给执行字典的实际构建之前检查重复的对列表。

这是检查重复对列表的一种方法的示例:

sample = [['a', 1], ['b', 2], ['c', 3], ['a', 2]]

def validate(pairs):
    # check for duplicate key names and raise an exception if any are found
    dups = []
    seen = set()
    for key_name,val in pairs:
        if key_name in seen:
            dups.append(key_name)
        else:
            seen.add(key_name)
    if dups:
        raise ValueError('Duplicate key names encountered: %r' % sorted(dups))
    else:
        return pairs

my_dict = dict(validate(sample))
于 2012-10-10T15:54:14.787 回答
0

字典不能包含双键。所以你需要做的就是执行代码然后转储repr()dict。

另一种选择是将字典项创建为(key, value)元组。通过将它们存储在一个列表中,您可以轻松地从它们创建一个 dict,然后检查len()dict/list 的 s 是否不同。

于 2012-10-10T09:40:03.120 回答