Создание словарей с предопределенными ключами

StackOverflow https://stackoverflow.com/questions/817884

  •  03-07-2019
  •  | 
  •  

Вопрос

Есть ли в python способ создать класс, который обрабатывается как словарь, но имеет предопределенные ключи при создании нового экземпляра?

Это было полезно?

Решение

Вы можете легко расширить любой встроенный тип. Вот как бы вы сделали это с помощью диктанта:

>>> 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, в которой говорится об этом, но очень популярная книга Dive Into Python (доступно бесплатно онлайн) имеет несколько примеров об этом.

Другие советы

Подкласс dict также может ограничивать ключи предопределенным списком, переопределяя __ 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

Да, в Python dict - это класс, поэтому вы можете создать его подкласс:

    class SubDict(dict):
        def __init__(self):
            dict.__init__(self)
            self.update({
                'foo': 'bar',
                'baz': 'spam',})

Здесь вы переопределяете метод dict __ init __ () (метод, который вызывается при создании экземпляра класса). Внутри __ init __ вы сначала вызываете метод supercalss __ init __ () , что является обычной практикой, когда вы хотите расширить функциональность базового класса. Затем вы обновляете новый экземпляр SubDictionary своими исходными данными.

    subDict = SubDict()
    print subDict    # prints {'foo': 'bar', 'baz': 'spam'}

Я не уверен, что это то, что вы ищете, но когда я прочитал ваше сообщение, я сразу же подумал, что вы хотите динамически генерировать ключи для подсчета упражнений.

В отличие от perl, который сделает это за вас по умолчанию,


grep{

Я не уверен, что это то, что вы ищете, но когда я прочитал ваше сообщение, я сразу же подумал, что вы хотите динамически генерировать ключи для подсчета упражнений.

В отличие от perl, который сделает это за вас по умолчанию,


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'

Python не даст вам это бесплатно:


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)

однако defaultdict сделает это за вас,

<*>{

Я не уверен, что это то, что вы ищете, но когда я прочитал ваше сообщение, я сразу же подумал, что вы хотите динамически генерировать ключи для подсчета упражнений.

В отличие от perl, который сделает это за вас по умолчанию,

<*>

Python не даст вам это бесплатно:

<*>

однако defaultdict сделает это за вас,

<*>}++} qw/ a a b c c c /; print map{

Я не уверен, что это то, что вы ищете, но когда я прочитал ваше сообщение, я сразу же подумал, что вы хотите динамически генерировать ключи для подсчета упражнений.

В отличие от perl, который сделает это за вас по умолчанию,

<*>

Python не даст вам это бесплатно:

<*>

однако defaultdict сделает это за вас,

<*>."\t".

Я не уверен, что это то, что вы ищете, но когда я прочитал ваше сообщение, я сразу же подумал, что вы хотите динамически генерировать ключи для подсчета упражнений.

В отличие от perl, который сделает это за вас по умолчанию,

<*>

Python не даст вам это бесплатно:

<*>

однако defaultdict сделает это за вас,

<*>{

Я не уверен, что это то, что вы ищете, но когда я прочитал ваше сообщение, я сразу же подумал, что вы хотите динамически генерировать ключи для подсчета упражнений.

В отличие от perl, который сделает это за вас по умолчанию,

<*>

Python не даст вам это бесплатно:

<*>

однако defaultdict сделает это за вас,

<*>}."\n"} sort {

Я не уверен, что это то, что вы ищете, но когда я прочитал ваше сообщение, я сразу же подумал, что вы хотите динамически генерировать ключи для подсчета упражнений.

В отличие от perl, который сделает это за вас по умолчанию,

<*>

Python не даст вам это бесплатно:

<*>

однако defaultdict сделает это за вас,

<*>{$b}

Я не уверен, что это то, что вы ищете, но когда я прочитал ваше сообщение, я сразу же подумал, что вы хотите динамически генерировать ключи для подсчета упражнений.

В отличие от perl, который сделает это за вас по умолчанию,

<*>

Python не даст вам это бесплатно:

<*>

однако defaultdict сделает это за вас,

<*>{$a}} keys %_; c 3 a 2 b 1

Python не даст вам это бесплатно:

<*>

однако defaultdict сделает это за вас,

<*>

Просто создайте подкласс dict и добавьте ключи в метод init .

class MyClass(dict)

def __init__(self):
    """Creates a new dict with default values""""

    self['key1'] = 'value1'

Помните, однако, что в python любой класс, который «действует как dict», обычно рассматривается как один, поэтому вам не нужно слишком беспокоиться о том, что он является подклассом, вместо этого вы можете реализовать методы dict, хотя Вышеупомянутый подход, вероятно, более полезен для вас:).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top