Python字典中的哈希

Python字典中的哈希,python,dictionary,Python,Dictionary,我有一个非常大的矩阵,我计划将其存储为Python中的字典列表。矩阵大部分是0,我想知道字典中的哈希函数是否会为每一行存储前导空间。例如,如果我初始化一个100000 x 100000的矩阵,但每行只有大约1000个条目存储实际元素,而对于第50000行,我有48500到50500个条目,Python会创建一个50500或2000大小的字典吗?此外,如果前者是真的,我有没有办法在Python当前的字典类中进行优化,或者我需要创建自己的字典类 作为我的代码示例,我有以下内容: class Dict

我有一个非常大的矩阵,我计划将其存储为Python中的字典列表。矩阵大部分是0,我想知道字典中的哈希函数是否会为每一行存储前导空间。例如,如果我初始化一个100000 x 100000的矩阵,但每行只有大约1000个条目存储实际元素,而对于第50000行,我有48500到50500个条目,Python会创建一个50500或2000大小的字典吗?此外,如果前者是真的,我有没有办法在Python当前的字典类中进行优化,或者我需要创建自己的字典类

作为我的代码示例,我有以下内容:

class DictArray:

    def __init__(self, width, height):
        self.Width = width
        self.Height = height
        self.Data = [0 for _ in range(self.Height) ]

    def __getitem__(self, k):
        if (self.Data[ k[0] ] == 0):
            return 0
        elif (k[1] in self.Data[ k[0] ]):
            return self.Data[ k[0] ][ k[1] ]
        else:
            return 0

    def __setitem__(self, k, value):
        if (self.Data[ k[0] ] == 0):
            self.Data[ k[0] ] = { k[1] : value }
        else:
            self.Data[ k[0] ][ k[1] ] = value

字典的大小将根据存储在其中的键的数量来确定

如果您有2000个键(每个键都是a
(x,y)
坐标,也许?),那么它的大小可以容纳2000个键(加上一点开销,以促进未来的增长,而无需调整大小)

但是,如果要为矩阵中的所有10^10个元素创建键(比如说,除2000个元素外,所有元素都引用
None
),那么您将拥有一个包含100亿个键的字典,它的大小将相应调整

使用字典构建稀疏矩阵非常简单:

class DictArray:
    def __init__(self, width, height):
        self.width = width
        self.height = height
        self._data = {}

    def _validate_coords(self, x, y):
        if not (0 <= x < self.width and 0 <= y < self.height):
            raise IndexError((x, y))

    def __getitem__(self, x_y):
        self._validate_coords(*x_y)
        return self._data.get(x_y, 0)

    def __setitem__(self, x_y, value):
        self._validate_coords(*x_y)
        if value == 0:
            try:
                del self._data[x_y]
            except KeyError:
                pass
        else:
            self._data[x_y] = value

然而,对于如此大的任务,我强烈建议您使用SciPy或NumPy。它们有专用于此类任务的数据结构,例如在中找到的任务。

字典将根据存储在字典中的键数调整大小

如果您有2000个键(每个键都是a
(x,y)
坐标,也许?),那么它的大小可以容纳2000个键(加上一点开销,以促进未来的增长,而无需调整大小)

但是,如果要为矩阵中的所有10^10个元素创建键(比如说,除2000个元素外,所有元素都引用
None
),那么您将拥有一个包含100亿个键的字典,它的大小将相应调整

使用字典构建稀疏矩阵非常简单:

class DictArray:
    def __init__(self, width, height):
        self.width = width
        self.height = height
        self._data = {}

    def _validate_coords(self, x, y):
        if not (0 <= x < self.width and 0 <= y < self.height):
            raise IndexError((x, y))

    def __getitem__(self, x_y):
        self._validate_coords(*x_y)
        return self._data.get(x_y, 0)

    def __setitem__(self, x_y, value):
        self._validate_coords(*x_y)
        if value == 0:
            try:
                del self._data[x_y]
            except KeyError:
                pass
        else:
            self._data[x_y] = value

然而,对于如此大的任务,我强烈建议您使用SciPy或NumPy。它们有专门用于此类任务的数据结构,例如。

如果您有一个稀疏矩阵,您可以尝试使用字典,其中键是(行、列)元组(或其他一些快速获取行和列的方法)

例如

关于字典性能,假设它具有对数搜索复杂度,您还可以查看它将占用多少内存。根据您使用的机器类型,10K条目的输入可能有效,但1000K条目的输入可能无效


(但是使用numpy或scipy可能是一个更好的选择)

如果您有一个稀疏矩阵,您可能会尝试使用字典,其中键是(行、列)元组(或其他一些快速获取行和列的方法)

例如

关于字典性能,假设它具有对数搜索复杂度,您还可以查看它将占用多少内存。根据您使用的机器类型,10K条目的输入可能有效,但1000K条目的输入可能无效


(但使用numpy或scipy可能是更好的选择)

向我们展示您如何初始化100000 x 100000矩阵。展示一个较小矩阵的示例,如果您想高效处理稀疏矩阵处理,保存其cipy和NumPy的字典可能就是您需要的库。这听起来绝对像是
scipy.sparse
的工作。SciPy的稀疏矩阵实现将比您所做的要好得多。您的
self.Data
是一个列表,不是字典。向我们展示您是如何初始化100000 x 100000矩阵的。展示一个较小矩阵的示例,如果您想有效地处理稀疏矩阵处理,保存其cipy和NumPy的字典可能就是您所需要的库。这听起来绝对像是
scipy.sparse
的工作。SciPy的稀疏矩阵实现将比您所做的要好得多。您的
self.Data
是一个列表,而不是一个字典。我喜欢您的建议。我会使用NumPy或SciPy来完成这个项目,但这个项目将在以后进行翻译,所以我希望尽可能少地依赖外部库possible@Woody1193:无论您将其翻译成何种语言,您可能也应该获得该语言的稀疏矩阵库,或者至少阅读标准稀疏矩阵格式和算法。标准方法将比您最初提出的方法表现得更好。我喜欢您的建议。我会使用NumPy或SciPy来完成这个项目,但这个项目将在以后进行翻译,所以我希望尽可能少地依赖外部库possible@Woody1193:无论您将其翻译成何种语言,您可能也应该获得该语言的稀疏矩阵库,或者至少阅读标准稀疏矩阵格式和算法。标准方法的性能将比您第一次想到的要好得多。
# assume get_matrix(i,j) gives your (i,j)th element
m = {}
for i in xrange(0,100000):
    for j in xrange(0,100000):
        t = get_matrix(i,j)
        if t:
            m[(i,j)] = t