Python 检查字典中的双键
可能重复:Python 检查字典中的双键,python,linux,Python,Linux,可能重复: 我最近正在生成包含数十万个键的大型词典(因此通过查看它们来发现错误是不可行的)。它们在语法上是正确的,但在某个地方有一个bug。它归结为“重复键”: 这段代码编译得很好,我不明白为什么a键的值是2,正如我所期望的1。现在问题很明显 问题是我今后如何防止这种情况发生。我认为这在python中是不可能的。我曾经 grep "'.*'[ ]*:" myfile.py | sort | uniq -c | grep -v 1 这不是防弹的。还有其他想法吗(在python中,这个grep只
我最近正在生成包含数十万个键的大型词典(因此通过查看它们来发现错误是不可行的)。它们在语法上是正确的,但在某个地方有一个bug。它归结为“重复键”: 这段代码编译得很好,我不明白为什么
a
键的值是2
,正如我所期望的1
。现在问题很明显
问题是我今后如何防止这种情况发生。我认为这在python中是不可能的。我曾经
grep "'.*'[ ]*:" myfile.py | sort | uniq -c | grep -v 1
这不是防弹的。还有其他想法吗(在python中,这个grep只是为了说明我所尝试的)
编辑:我不想要重复的键,只需要发现这种情况并手动编辑数据dict不能包含双键。因此,您只需执行代码,然后转储dict的
repr()
另一个选项是将dict项创建为
(键,值)
元组。通过将它们存储在一个列表中,您可以轻松地从它们创建一个dict,然后检查dict/列表的len()
s是否不同。如果您需要每个键有多个值,您可以使用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']})
>>从集合导入defaultdict
>>>数据目录=默认目录(列表)
>>>数据dict['key'].追加('value')
>>>数据字典
defaultdict(,{'key':['value']})
>>>数据dict['key'].append('second'u value')
>>>数据字典
defaultdict(,{'key':['value','second_value']})
您是否正在生成包含大型词典的Python文件?比如:
print "{"
for lines in file:
key, _, value = lines.partition(" ")
print " '%s': '%s',"
print "}"
如果是这样的话,您就没有什么办法来防止这种情况,因为您无法轻松覆盖内置的dict的构造
相反,我建议您在构造字典字符串时验证数据。您还可以生成不同的语法:
dict(a = '1', a = '2')
…如果密钥重复,将生成一个语法错误。但是,它们并不完全相同,因为字典键比关键字args灵活得多(例如,{123:''.''''''.}是有效的,但是
dict(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
您没有确切说明或显示如何生成重复关键点所在的位置。但这就是问题所在
我建议您不要使用类似于{'a':1,,'a':2}
的方式来构建字典,而是使用以下形式:dict([['a',1],…,['a',2]])
,它将从提供的[键,值]
对列表中创建一个字典。这种方法允许您在将对列表传递给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))
您的数据中是否存在重复密钥的问题?这意味着您希望对它们进行标记(或忽略重复项)。最简单的方法是创建并使用dict的自定义子类(请参见上面问题的链接),当您尝试添加重复项时,该子类将失败,并显示信息性错误消息。你甚至可以修改行为来忽略重复,如果这是你真正想要的。现在我看到这实际上是一个重复,这个答案解决了我的问题。我想知道为什么这样的行为(通知用户他正在复制密钥)在Python中不是默认的,我无法想象需要将密钥加倍的情况。我是否应该关闭/删除此问题?(如何?)内存中的dict
对象不能包含重复的键(具有相同哈希的相等对象)。如何将字典序列化为文件?问题是dict可以包含双键,正如我的问题所示,但它会以静默方式重新分配新值。repr()
将如何帮助我?请记住,字典是巨大的,我无法通过查看转储数据的MBs来推断任何内容。我觉得你答案的第二部分很有价值,尽管它会降低我代码的可读性。ThanksIt不会检测到它们,但您可以创建一个没有这些重复项的新dict。@user35186:Python字典不能包含重复的键。另一方面,基本上是一个字符串表示,可以用来构造字典,可以包含它们。这就是你在问题中表现出来的。您需要在正在创建的字典显示中检测重复项。抱歉,我没有说清楚,当然它不能像您和其他人指出的那样在内存中包含重复的键,但它可以在代码中、在字符串表示中,并生成有效(但误导)语法。
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))