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