默认为密钥的Python字典?

Python dictionary that defaults to key?

有没有办法让defaultdict默认返回密钥? 或者一些具有同等行为的数据结构? 即,在初始化字典d之后,

1
2
3
4
5
6
7
>>> d['a'] = 1
>>> d['a']
1
>>> d['b']
'b'
>>> d['c']
'c'

我只看到默认字典采用不带参数的函数,所以我不确定除了创建一种新的字典之外是否还有其他解决方案。


我将覆盖dict__missing__方法:

1
2
3
4
5
6
7
8
9
10
>>> class MyDefaultDict(dict):
...     def __missing__(self, key):
...         self[key] = key
...         return key
...
>>> d = MyDefaultDict()
>>> d['joe']
'joe'
>>> d
{'joe': 'joe'}


编辑:哎呀,我刚刚意识到我文件中的代码最初来自另一个stackoverflow答案! https://stackoverflow.com/a/2912455/456876,请继续投票。

这就是我使用的 - 它是一个defaultdict变体,它将键作为参数传递给默认值工厂函数,该函数作为参数传递给init,而不是参数:

1
2
3
4
5
6
7
class keybased_defaultdict(defaultdict):
    def __missing__(self, key):
        if self.default_factory is None:
            raise KeyError(key)
        else:
            value = self[key] = self.default_factory(key)
            return value

这是你想要的用途:

1
2
3
4
5
>>> d = keybased_defaultdict(lambda x: x)
>>> d[1]
1
>>> d['a']
'a'

其他可能性:

1
2
3
4
5
>>> d = keybased_defaultdict(lambda x: len(x))
>>> d['a']
1
>>> d['abc']
3


如果您不想继承dict,可以尝试使用

1
2
3
d.get('a', 'a')
d.get('b', 'b')
d.get('c', 'c')

我觉得这个目的更清晰,更不神奇

如果你是一个DRY狂热者并且只有一个char键,你可以这样做:)

1
2
3
d.get(*'a'*2)
d.get(*'b'*2)
d.get(*'c'*2)

您可能必须编写自己继承自(或类似于)defaultdict的类并覆盖__getitem__方法。