如何修复使用自定义词典时的键错误

2024-10-01 09:24:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试做以下事情:解析音乐文件夹中的所有文件,如果它们在我的收藏夹中,将它们复制到单独的文件夹中。在

为了实现这一点,我用我喜欢的轨迹解析一个xml,并使用这些信息创建一个像这样的定制字典

lovedSongs[artist][title] = 1

当我解析文件夹中的文件时,我从id3标记中读取歌曲标题和艺术家,理论上,我尝试查看lovedSongs[tagArtist][tagTitle]是否为1

^{pr2}$

当我试图运行.py文件时,我得到一个dictionary Key Error。我在这里找到了一个潜在的答案:How to make a python dictionary that returns key for keys missing from the dictionary instead of raising KeyError?并像下面那样应用它,但是我仍然得到了密钥错误

class SongDict(dict):
    def __init__(self, default=None):
        self.default = default

    def __getitem__(self, key):
        if not self.has_key(key):
            self[key] = self.default()
        return dict.__getitem__(self, key)

    def __missing__(self, key):
        return 0

最好的解决方案是什么?使用try/except也许代替简单的if?在

另外,我想我应该提一下,我是python的新手,只有几个小时的“经验”,这是我学习python语言的方法。在


Tags: 文件keyself文件夹defaultdictionaryreturnif
2条回答

听起来你真正想要的是一个简单的set

for filename in filelist:     
    if filename.endswith(".mp3"):
        try:
            id3r = id3reader.Reader(filename)
        except (UnicodeDecodeError, IOError):
            pass
        else:
            artist = ensureutf8andstring(id3r.getValue('performer'))
            title = ensureutf8andstring(id3r.getValue('title'))

            if artist != "None" or title != "None":
                if (artist, title) in lovedSongs:
                    print artist + ' - ' + title

您可以尝试使用defaultdict,参数是defaultdict(dict)。无论何时尝试引用不存在的值,它都不会引发错误,而是返回指定值的默认空值:

In [7]: from collections import defaultdict

In [8]: lovedsongs = defaultdict(lambda: defaultdict(dict))

In [9]: lovedsongs['OAR']['Blackrock'] = 1

In [10]: lovedsongs['Timati']['Moj Put'] = 1

In [11]: lovedsongs
Out[11]: defaultdict(<function <lambda> at 0x24e5ed8>, {'Timati': defaultdict(<type 'dict'>, {'Moj Put': 1}), 'OAR': defaultdict(<type 'dict'>, {'Blackrock': 1})})

In [12]: lovedsongs['Not']['Found']
Out[12]: {}

In [13]: if lovedsongs['Not']['Found'] == 1:
   ....:     print 'Found it'
   ....:
   ....:

In [14]: if lovedsongs['OAR']['Blackrock'] == 1:
   ....:     print 'Found it'
   ....:
   ....:
Found it

通过观察单个级别(即“更规则”)defaultdict的工作方式,可以更好地理解defaultdict(lambda: defaultdict(dict))语法:

^{pr2}$

我们用一个参数int声明了defaultdict-这意味着如果找不到值,而不是抛出错误,我们将只返回{}(因为0是一个整数的空值)。如果我们使用str,我们将得到'',如果我们使用dict,我们将得到一本字典。然而,这种情况下最棘手的部分是您有一个嵌套字典(defaultdict(dict)),如果您试图引用嵌套字典中不存在的键,则会遇到相同的问题:

In [13]: d = defaultdict(dict)

In [14]: d['three']['more']
                                     -
KeyError                                  Traceback (most recent call last)

/path/<ipython console> in <module>()

KeyError: 'more'

因此,为了使我们的嵌套字典也成为defaultdict,我们必须做一些技巧:因为defaultdict的参数是需要可调用的(但尚未调用->;请参见intint()),我们使用一个lambda函数来模拟这种行为。在一个非常简单的层次上,可以将lambda看作是阻止{}在需要之前被调用。现在,您将拥有一个字典(带有嵌套字典),它将处理两个级别的缺失键,而不会引发错误。希望能解释一下。在

相关问题 更多 >