В каком случае я бы использовал кортеж в качестве словарного ключа? - PullRequest
58 голосов
/ 21 декабря 2009

Я изучал разницу между списками и кортежами (в Python). Очевидным является то, что кортежи являются неизменяемыми (значения не могут быть изменены после первоначального назначения), а списки являются изменяемыми.

Предложение в статье меня достало:

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

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

Изменить:

Спасибо за ваши примеры. Насколько я понимаю, очень важным приложением является кэширование значений функций.

Ответы [ 11 ]

89 голосов
/ 21 декабря 2009

Классический пример: Вы хотите сохранить значение точки как кортеж (x, y)

24 голосов
/ 21 декабря 2009
salaries = {}
salaries[('John', 'Smith')] = 10000.0
salaries[('John', 'Parker')] = 99999.0

РЕДАКТИРОВАТЬ 1 Конечно, вы можете сделать salaries['John Smith'] = whatever, но тогда вам придется проделать дополнительную работу, чтобы разделить ключ на имя и фамилию. Что касается pointColor[(x, y, z)] = "red", то здесь преимущество ключа кортежа более заметно.

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

РЕДАКТИРОВАТЬ 0

Кстати, каждый элемент кортежа тоже должен быть хэшируемым:

>>> d = {}
>>> t = (range(3), range(10, 13))
>>> d[t] = 11
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list objects are unhashable
>>>
7 голосов
/ 21 декабря 2009

Я использую кортеж много раз в качестве клавиши dict, например,

  • Я использую их, когда мне нужно создать уникальный ключ из нескольких значений, например

    на основе first_name, ключ last_name может быть ключом = '%s_%s'%(first_name, last_name), но лучший способ - key = (first_name, last_name), потому что

    1. Это более читабельно, короче и меньше вычислений
    2. Проще получить отдельные значения
    3. Наиболее важно key = '%s_%s'%(first_name, last_name) неверно и может не давать уникальные ключи для всех значений first_name и last_name, например. когда значения содержат _
  • Кэширование результатов функции

    def func(a1, b1):
        if (a1,b1) in cache: return cache[(a1,b1)]
        ...
    
4 голосов
/ 30 мая 2016

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

Например: {(<x-coordinate>,<y-coordinate>): <indicating letter>}

Здесь, если мы будем использовать x-coordinate или y-coordinate отдельно, мы не будем представлять эту точку.

4 голосов
/ 21 декабря 2009

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

т.е.

seen = {}
seen[('abc', 'lax')] = 1
seen[('xyz', 'nyc')] = 1
2 голосов
/ 18 ноября 2017

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

Допустим, вы ищете лучшую комбинацию гиперпараметров для learning_rate, regularization_factor и model_complexity.

Тогда у вас может быть словарь в Python, в котором вы можете составить другую комбинацию, которую эти hparams могут принимать как ключи и соответствующие им весовые матрицы из алгоритма обучения как значения

hparams_hist = {}
hparams_hist[(0.001, 0.7, 5)] = weight_matrix1
hparams_hist[(0.0001, 0.8, 2)] = weight_matrix2

Эти весовые матрицы необходимы для прогнозирования в реальном времени.

2 голосов
/ 22 октября 2016

Вы можете использовать его для примерно постоянного поиска точки в пространстве поиска. Например, вы можете использовать его для задачи удовлетворения ограничений, где каждый кортеж может содержать некоторые ограничения. Ограничение может иметь форму (v1.v2), где color (v1)! = Color (v2) для окрашивания prob и т. Д. Используя кортежи в качестве ключей словаря, вы сможете в постоянное время определить, удовлетворяет ли перестановка ограничению или нет.

2 голосов
/ 21 декабря 2009

Полагаю, в случае сортировки может быть полезным использование кортежа. Например, предположим, что ключ словаря представляет поле сортировки (очевидно, будет поле сортировки по умолчанию, чтобы ключ не был None). Если вам нужно несколько полей сортировки, например, в случае сортировки по фамилии, а затем по имени, будет ли хорошей идеей использовать кортеж в качестве ключа словаря?

Конечно, такая идея может иметь ограниченное использование, но это не значит, что она абсолютно бесполезна.

1 голос
/ 06 мая 2016
def getHash(word):
    result={}
    for i in range(len(word)):
        if word[i] in result:
            result[word[i]]+=1
        else :
            result[word[i]]=1

    return tuple (sorted((result.items())))


def groupAnagrams(words):
    resultHash={}
    for i in range(len(words)):
        s=getHash(words[i].lower())
        #print s
        if s in resultHash :
            l=list(resultHash[s]) 
            l.append(words[i])
            resultHash[s] = l # list(resultHash[s]).append(words[i])  
        else :
            resultHash[s]=[words[i]] # Creating list 

    return resultHash.values()
1 голос
/ 10 июля 2014

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

Например, , считая, сколько людей нажали на изображение3 после наведения текста 2.

    funnels = defaultdict(int)
    funnels[('hovered_text2', 'clicked_image3')] += 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...