Словарные ключи Python помимо строк и целых чисел? - PullRequest
26 голосов
/ 03 декабря 2010

У кого-нибудь есть несколько хороших примеров словарей с некоторыми интересными ключами (кроме канонической строки или целого числа), и как вы использовали их в своей программе?

Я понимаю, все, что нам нужно для ключа, это что-то hashable означает, что он должен быть неизменным и сопоставимым (имеет метод __eq__() или __cmp__()).

Смежный вопрос: как я могу быстро и плавно определить новый hashable?

Ответы [ 5 ]

31 голосов
/ 03 декабря 2010

Давайте перейдем к чему-то более эзотерическому. Предположим, вы хотите выполнить список функций и сохранить результат каждой из них. Для каждой функции, которая вызвала исключение, вы хотите записать исключение, а также вести подсчет того, сколько раз вызывается каждый вид исключения. Функции и исключения могут использоваться как клавиши dict, так что это легко:

funclist = [foo, bar, baz, quux]

results    = {}
badfuncs   = {}
errorcount = {}

for f in funclist:
    try:
        results[f] = f()
    except Exception as e:
        badfuncs[f]   = e
        errorcount[type(e)] = errorcount[type(e)] + 1 if type(e) in errorcount else 1

Теперь вы можете выполнить if foo in badfuncs, чтобы проверить, вызвала ли эта функция исключение (или if foo in results, чтобы проверить, правильно ли она работает), if ValueError in errorcount, чтобы узнать, была ли вызвана какая-либо функция ValueError, и т. Д.

10 голосов
/ 03 декабря 2010

Вы можете использовать кортеж в качестве ключа, например, если вы хотите создать многостолбцовый индекс.Вот простой пример:

>>> index = {("John", "Smith", "1972/01/01"): 123, ("Bob", "Smith", "1972/01/02"): 124}
>>> index
{('Bob', 'Smith', '1972/01/02'): 124, ('John', 'Smith', '1972/01/01'): 123}
>>> index.keys()
[('Bob', 'Smith', '1972/01/02'), ('John', 'Smith', '1972/01/01')]
>>> index['John', 'Smith', '1972/01/01']
123

Пример того, как использовать dict в качестве ключа (хешируемый dict), смотрите в следующем ответе: Python hashable dicts

8 голосов
/ 03 декабря 2010

Вы исключили, вероятно, самый важный метод для объекта: hashable : __hash__().

Кратчайшая реализация вашего собственного типа hashable:

class A(object):
    pass

Теперь вы можете использовать экземпляры A в качестве ключей словаря:

d = {}
a = A()
b = A()
d[a] = 7
d[b] = 8

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

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

3 голосов
/ 03 декабря 2010

Обратите внимание, что я никогда не использовал это на самом деле, но я всегда думал, что использование кортежей в качестве ключей может позволить вам сделать некоторые интересные вещи. Я бы нашел, например, удобный способ для отображения координат сетки. Вы можете думать об этом как о сетке в видеоигре (может быть, какая-то тактическая игра, например Fire Emblem ):

>>> Terrain = { (1,3):"Forest", (1,5):"Water", (3,4):"Land" }
>>> print Terrain
{(1, 5): 'Water', (1, 3): 'Forest', (3, 4): 'Land'}
>>> print Terrain[(1,3)]
Forest
>>> print Terrain[(1,5)]
Water
>>> x = 3
>>> y = 4
>>> print Terrain[(x,y)]
Land

Нечто подобное.

Редактировать: Как отметил Марк Рушаков в комментариях, я в основном намерен, чтобы это был разреженный массив .

1 голос
/ 25 января 2018

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

foo = { 1:'this', 2:'that', 'more':'other', 'less':'etc' }

является полностью действительным словарем, который обеспечивает доступ к foo[2] так же легко, как и к foo['more']. * 1008.*

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...