在Python中,是否有一种方法可以创建一个类,该类被视为字典,但在创建新实例时具有预定义的键?
你还可以通过覆盖__setitem__()
方法,使字典子类将键限制为预定义列表。
>>> class LimitedDict(dict):
_keys = "a b c".split()
def __init__(self, valtype=int):
for key in LimitedDict._keys:
self[key] = valtype()
def __setitem__(self, key, val):
if key not in LimitedDict._keys:
raise KeyError
dict.__setitem__(self, key, val)
>>> limited = LimitedDict()
>>> limited['a']
0
>>> limited['a'] = 3
>>> limited['a']
3
>>> limited['z'] = 0
Traceback (most recent call last):
File "<pyshell#61>", line 1, in <module>
limited['z'] = 0
File "<pyshell#56>", line 8, in __setitem__
raise KeyError
KeyError
>>> len(limited)
3
你可以轻松地扩展任何内置类型。以下是如何使用字典进行扩展:
>>> class MyClass(dict):
... def __init__(self, *args, **kwargs):
... self['mykey'] = 'myvalue'
... self['mykey2'] = 'myvalue2'
...
>>> x = MyClass()
>>> x['mykey']
'myvalue'
>>> x
{'mykey2': 'myvalue2', 'mykey': 'myvalue'}
我找不到讲解这个问题的 Python 文档,但非常受欢迎的书籍《Python 禅意花园》(可免费在线阅读)提供了一些示例。
是的,在Python中dict
是一个类,因此您可以对其进行子类化:
class SubDict(dict):
def __init__(self):
dict.__init__(self)
self.update({
'foo': 'bar',
'baz': 'spam',})
在这里,你覆盖了字典的__init__()
方法(这是在类的实例创建时调用的方法)。在__init__
内部,你首先调用超类的__init__()
方法,这是一种常见的做法,当你想要扩展基类功能时。然后,你使用初始数据更新了SubDictionary
的新实例。
subDict = SubDict()
print subDict # prints {'foo': 'bar', 'baz': 'spam'}
我不确定这是否符合您的要求,但当我阅读您的帖子时,我立即想到您正在寻找动态生成计数练习密钥。
与 Perl 不同,它会默认为您执行此操作,
grep{$_{$_}++} qw/ a a b c c c /;
print map{$_."\t".$_{$_}."\n"} sort {$_{$b}$_{$a}} keys %_;
c 3
a 2
b 1
Python不会免费为您提供这个:
l = ["a","a","b","c","c","c"]
d = {}
for item in l:
d[item] += 1
Traceback (most recent call last):
File "./y.py", line 6, in
d[item] += 1
KeyError: 'a'
然而,defaultdict会为您完成这项工作,
from collections import defaultdict
from operator import itemgetter
l = ["a","a","b","c","c","c"]
d = defaultdict(int)
for item in l:
d[item] += 1
dl = sorted(d.items(),key=itemgetter(1), reverse=True)
for item in dl:
print item
('c', 3)
('a', 2)
('b', 1)
只需创建 dict 的子类并在 init 方法中添加键即可。
class MyClass(dict)
def __init__(self): """创建一个带有默认值的新字典"""
self['key1'] = 'value1'
请记住,在 Python 中,任何“像字典一样”的类通常都会被视为字典,因此您不必太担心它是子类,您可以实现 dict 方法,尽管上述方法可能对您更有用 :)