90

我正在研究列表和元组之间的区别(在 Python 中)。一个明显的问题是元组是不可变的(初始赋值后值不能更改),而列表是可变的。

文章中的一句话让我明白了:

只有不可变元素可以用作字典键,因此只有元组而不是列表可以用作键。

我很难想到我想使用元组作为字典键的情况。您能否提供一个自然、高效、优雅或显而易见的解决方案的示例问题?

编辑:

谢谢你的例子。到目前为止,我认为一个非常重要的应用是函数值的缓存。

4

12 回答 12

123

经典示例:您希望将点值存储为 (x, y) 的元组

于 2009-12-21T07:14:10.687 回答
34
salaries = {}
salaries[('John', 'Smith')] = 10000.0
salaries[('John', 'Parker')] = 99999.0

编辑 1 当然你可以这样做salaries['John Smith'] = whatever,但是你必须做额外的工作才能将密钥分成名字和姓氏。怎么样pointColor[(x, y, z)] = "red",这里 tuple key 的好处更加突出。

我必须强调,这不是最佳做法。在许多情况下,您最好创建特殊类来处理此类情况,但 Arrieta 要求提供示例,我给了她(他)。

编辑 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
>>>
于 2009-12-21T07:06:10.223 回答
8

我使用元组很多时间作为dict关键,例如

  • 当我必须从多个值创建唯一键时,我会使用它们,例如

    基于first_name, last_namekey 可能是 key ='%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)]
        ...
    
于 2009-12-21T07:36:46.120 回答
5

我在按地理位置比较网络设备的应用程序中使用元组作为字典键。由于每个位置的设备名称相似,因此它提供了一种自然的方式来了解在处理多个设备时是否已经看到与该配对匹配的设备。

IE

seen = {}
seen[('abc', 'lax')] = 1
seen[('xyz', 'nyc')] = 1
于 2009-12-21T07:37:37.633 回答
5

当您想要显示多个元素一起形成一个键时,您可以使用元组作为键。

例如:{(<x-coordinate>,<y-coordinate>): <indicating letter>}

在这里,如果我们单独使用x-coordinateor y-coordinate,我们将不会代表这一点。

于 2016-05-30T04:09:37.570 回答
5

在机器学习和深度学习的上下文中,如果您正在对最佳超参数进行超参数搜索,那么使用元组作为键绝对是非常有用的。

假设您正在寻找 、 和 的最佳超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

进一步需要这些权重矩阵来进行实时预测。

于 2017-11-18T16:40:06.623 回答
4
a[("John", "Doe")] = "123 Fake Street"
于 2009-12-21T07:06:05.183 回答
2

我想在排序的情况下,使用元组可能会有好处。例如,假设字典键表示一个排序字段(显然会有一个默认的排序字段来防止键是None)。如果您需要多个排序字段,例如按姓氏排序,然后按名字排序,使用元组作为字典键不是一个好主意吗?

当然,这样的想法可能用途有限,但这并不意味着它完全没用。

于 2009-12-21T07:22:40.730 回答
2

如果您正在构建基本分析工具,则可以将其用于漏斗分析。

例如,计算有多少人在将鼠标悬停在 text2 上后点击了 image3。

    funnels = defaultdict(int)
    funnels[('hovered_text2', 'clicked_image3')] += 1
于 2014-07-09T20:56:34.420 回答
2

您可以将其用于搜索空间中某个点的近似恒定时间搜索。例如,您可以将其用于约束满足问题,其中每个元组可能包含一些约束。约束可能是 (v1.v2) 的形式,其中 color(v1)!=color(v2) 用于着色概率等。使用元组作为字典键,您将能够在恒定时间内判断排列是否满足约束.

于 2016-10-22T07:56:21.707 回答
1
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()
于 2016-05-06T17:42:00.930 回答
0

我认为元组作为字典键会很好,如果我们要存储:-

  1. 坐标系中的一些点。

  2. 有助于在下一次迭代中标记您想要的矩阵的位置。例如:-

    flag = {(0,1): True, (1,0) = False}

于 2022-02-14T00:33:46.210 回答