我想使用二维数组作为哈希表,在 C 中,它就像:
hash[1][2] = 1
在 Python 中,我尝试过:
hash = {}
hash[1,2] = 1
但事实证明速度很慢。
那么如何在 Python 中高效地实现一个二维哈希表呢?
更新:
我的程序是一个计算繁重的程序。由于 Python dict 动态分配内存,我可以看到程序在运行时正在等待内存分配,而 CPU 使用率时而低时而高。
C 风格的二维数组应该没问题,但我不知道如何在 Python 中实现它。
我想使用二维数组作为哈希表,在 C 中,它就像:
hash[1][2] = 1
在 Python 中,我尝试过:
hash = {}
hash[1,2] = 1
但事实证明速度很慢。
那么如何在 Python 中高效地实现一个二维哈希表呢?
更新:
我的程序是一个计算繁重的程序。由于 Python dict 动态分配内存,我可以看到程序在运行时正在等待内存分配,而 CPU 使用率时而低时而高。
C 风格的二维数组应该没问题,但我不知道如何在 Python 中实现它。
您的代码是否正常取决于您的用例。如果你想要类似的东西,即这样你就可以在不接触其他元素的情况下hash[1][2]
进行迭代,元组键不是一个好的解决方案。在这种情况下,你最好这样做:hash[x]
hash[y]
from collections import defaultdict
hash = defaultdict(dict)
hash[1][2] = 1
这使得hash
包含其他 dicts 的 dict 代替具有复合(元组)键的单个 dict。使用defaultdict
is 主要是为了避免hash.setdefault(1, {})
调用创建 subdicts,以防它们尚不存在。
你用复合键做了1级dict:
arr = { (1,2): "a", (1,3): "b" }
另一种选择是 2 级字典:
arr = { 1: { 2: "a", 3: "b" }}
还有一个是使用例如 numpy.array(),IIRC 它不能是稀疏的。
scipy 有可能有用的稀疏 marix 类。
如果您遵循以下代码,您可以执行类似于 C 的操作:
a={}
a[1]={}
a[2]={}
现在 'a' 是模拟您的用例的字典字典。现在您可以将其用作:
a[1][1] = anyVal;
a[1][2] = otherVal;
a[2][1] = anotherVal;
等等等等……
如果可能的键集很小,您还可以使用列表列表。这是一个非常简单的马尔可夫生成器,它使用输入语料库中的字符对来创建新的“句子”。请注意 list-of-lists 的初始化markov_pairs
,这是使用 Python 列表获取 2D 数组的方式。
import random
import string
all_letters = string.ascii_uppercase + string.ascii_lowercase
corpus = """Lorem ipsum dolor sit amet, consectetur
adipisicing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum."""
# normalize all spaces to single spaces
corpus = ' '.join(corpus.split())
# initialize 2-D array for sequence tally
markov_pairs = [[0]*256 for i in range(256)]
# make sure every letter and space has at least *some* probability of following
# any other letter
for sublist in markov_pairs:
for i in range(len(sublist)):
if chr(i) in all_letters+' ':
sublist[i] += 1
# pairwise iterate over input corpus, updating markov pairs with observed pairs
it = iter(corpus)
last = next(it)
for c in it:
markov_pairs[ord(last)][ord(c)] += 10000
last = c
# function to guess a next character, given a starting character, based on the
# frequencies found in the input corpus
def getNext(pairs, from_):
probs = pairs[ord(from_)]
num = random.randint(0,sum(probs))
# reorder probs so highest weights are up front
for p,c in sorted(((p,chr(i)) for i,p in enumerate(probs) if p),reverse=True):
num -= p
if num <= 0: break
return c
# generate some new text based on the corpus
for i in range(20):
ret = []
last = random.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
while last in (all_letters+' '):
ret.append(last)
last = getNext(markov_pairs, last)
print ''.join(ret)
版画(有点像拉丁和图雷特综合症的混合体):
NEx quite eria nalorunorein ulag Utalidor eniqum atet
SPllalalad nsiqudont intret
RCve ollat rim don epored lonidolid im cuatempt esepiaent furiutautr lit m vehenise vex nst
Wveta cet at mp icur e co anorepit pidomodor ng ala
Lorurim
Fm dorisseiuimondedor nid lunor
HJcupter Excarcuro don itaboffuitese cosensest emm cim e ct vonut s cosudodisir
Habocinim issit nia iat uininolla iatere e a aulict catenipa pont
Sgiteps a t cor
PRRfinsmabommo dupagnit norer olulaboi mipit
Exearicat ites e ngn ptrequmpa n uiuia imema cuause dont
Ex inod in amost met
Ae s cutes ia
CKx fint m e cor olllulalicun sedoreuipa ciuam
Oorolatrenor cum a is d Dum e edocipit m cimont eum lliofinsit aret am elorellisterexereminidit elolititresuntexelimomp poisudinisenorute a abolor ex ont
BZt ret taenorenat miqururcon Duit sea ca vexexeserurisulollat
Tlit aboceda qupriut m cualllupip cad d s dect
Ohet em uidid iam it d edollat a ssicaruir idor d unon n e e colaum funsiabontiataboressusia ffise Dum vororeruisedor redeit aupos cat epom ipt
GDust
Hyalorunofit d qur enser