如何在Python字典中将列表用作键

3

我想使用以下字典:

示例: {[8, 16]:[[1,2,4,8],8], [16, 24]: [[1,2,3,4,8,12], 12]}

8和16是将要输入的两个数字,我需要构建上述字典。

使用setdefault,我可以为字典中的值创建一个列表,但不能为键创建一个列表。

下面是我的代码:

#!/usr/bin/env python
"""
        This Program calculates common factors between two Numbers , which 
        is stored on a list and also greatest common factor is also computed.
        All this is stored in a dictionary
        Example: { '[n1, n2]': [[Commonfac1(n1,n2), Commonfac2(n1,n2)....Commonfacn(n1,n2)],GreatestCommonFactor] }
"""
def Factors(number):
        result = []
        for i in range(1, number+1):
                if (number % i) == 0:
                        result.append(i)

        return result

def Common_Factors(n1, n2):
        result = []
        for element in n1:
                if element in n2:
                        result.append(element)

        return result

def greatest_common_factor(common_factors):
        count = 0
        length = len(common_factors)
        current_largest = common_factors[count]
        for i in common_factors:
                count += 1
                if count <= length -1:
                        if current_largest < common_factors[count]:
                                current_largest = common_factors[count]
        return current_largest


def main():
        n1 = 8
        n2 = 16
        result1 = Factors(n1)
        result2 = Factors(n2)

        CF = Common_Factors(result1, result2)

        GCF = greatest_common_factor(CF)

        dict = {}

        dict.setdefault([n1, n2], []).append(CF)
        print dict

if __name__ == '__main__':
        main()

当我运行上述程序时,我遇到以下错误:
$ python math74.py 
Traceback (most recent call last):
  File "math74.py", line 58, in <module>
    main()
  File "math74.py", line 54, in main
    dict.setdefault([n1, n2], []).append(CF)
TypeError: unhashable type: 'list'

请问如何实现上述功能?

为了更加清晰,下面是示例数据: {[8, 16]:[[1,2,4,8],8], [16, 24]: [[1,2,3,4,8,12], 12]}

其中8和16是用户输入的两个数字,1、2、4、8是它们的公因数,而8是最大公因数。


8
在将列表插入字典之前,将其转换为元组吗? - Jon Clements
1
为什么要使用可变容器作为键? - user1971598
继Jon Clements的评论之后,Python的语法也很好地支持将元组作为字典键。考虑以下示例字典:d = {(1,2) : 3, (10,20) : 30}。要访问一个键,您可以这样写:d[1,2] - FMc
有件事值得思考:如果你执行 a = [8,16]d[a] = [[1,2,4,8],8]a.append(32),会发生什么? - Adam Smith
@EdgarAroutiounian 这可能会有用吗?我明白你为什么不能这样做,但仅仅因为你不能使用哈希映射来实现它,并不意味着这个概念在所有情况下都是无用的。 - Andreas Vinter-Hviid
2个回答

5

您可能不需要一个列表,因为:

  1. 列表是可变的,这意味着它可以更改(删除/添加/修改)其值。例如:
>>> testList = [1,5]
>>> d = {"myList": testL}
>>> d
{'myList': [1, 5]}
>>> testList.append(53)
>>> d
{'myList': [1, 5, 53]}
>>> 

如您所见,列表可以被更改,并且键需要是唯一的。
对于不可变的数组类型,Python 有元组。一旦定义了元组,它就不能被修改。这意味着,您也可以将其用作目录中的键:

>>> myTuple = (4, 5)
>>> myDict = {myTuple: "here is the value"}
>>> myDict
{(4, 5): 'here is the value'}
>>> myTuple.append(9)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'append'

感谢@Matt3o12的回复,现在我明白了。 - Niranjan M.R

2

正如先前提到的,您可能想将列表转换为元组,以使其可哈希。

另一种方法,特别适用于一些更复杂的对象,可以使用pickle库来序列化对象。

例如:

import pickle

my_list = [8, 16]
my_value = 'some_value'
my_dict = {pickle.dumps(my_list): my_value}

my_dict[pickle.dumps([8, 16])]  # This equals to 'some_value'

@rroszkowaik 感谢您的回复,我会研究一下pickle。 - Niranjan M.R
使用pickle并不是一个好主意。Pickle的作用是将值序列化并保存在磁盘上(或其他地方),以便Python在脚本终止时可以恢复其状态(值等)。 - Matt3o12
不一定。这里有一个很好的pickle使用示例,用于创建字典键:https://dev59.com/OW445IYBdhLWcg3w1tui。我同意在这种情况下转换为元组是一种方法。 - Radosław Roszkowiak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接