Python 为字符串指定唯一整数id的最有效方法是什么?
我编写的程序处理大量对象,每个对象都有自己唯一的id,而id本身就是一个复杂结构的字符串(对象的十几个唯一字段由一些分隔符连接),长度很大 由于我必须快速处理大量这些对象,并且在处理时需要通过id引用它们,而且我没有能力更改它们的格式(我通过网络从外部检索它们),因此我希望将它们复杂的字符串id映射到我自己的内部整数id,并进一步使用它进行比较,以便将它们进一步传输到其他进程,等等 我要做的是使用一个简单的dict,其中键作为对象的字符串id,整数值作为对象的内部整数id 我的问题是:Python中有没有更好的方法来实现这一点?也许有一种方法可以手动计算一些散列,不管怎样?也许口述不是最好的解决办法Python 为字符串指定唯一整数id的最有效方法是什么?,python,hash,Python,Hash,我编写的程序处理大量对象,每个对象都有自己唯一的id,而id本身就是一个复杂结构的字符串(对象的十几个唯一字段由一些分隔符连接),长度很大 由于我必须快速处理大量这些对象,并且在处理时需要通过id引用它们,而且我没有能力更改它们的格式(我通过网络从外部检索它们),因此我希望将它们复杂的字符串id映射到我自己的内部整数id,并进一步使用它进行比较,以便将它们进一步传输到其他进程,等等 我要做的是使用一个简单的dict,其中键作为对象的字符串id,整数值作为对象的内部整数id 我的问题是:Pytho
至于数字:系统中一次大约有10万个这样的唯一对象,因此整数容量就足够了。出于比较目的,您可以
插入字符串,然后将它们与is
进行比较,而不是=
,后者进行简单的指针比较,速度应尽可能快(或快于)比较两个整数:
>>> 'foo' * 100 is 'foo' * 100
False
>>> intern('foo' * 100) is intern('foo' * 100)
True
intern
保证id(intern(A))==id(intern(B))
iffA==B
。请确保intern
任何字符串一经输入就立即输入。请注意,intern
在Python 3.x中被称为sys.intern
但是当您必须将这些字符串传递给其他进程时,您的dict
解决方案似乎是最好的
str_to_id = {}
for s in strings:
str_to_id.setdefault(s, len(str_to_id))
所以整数容量已经足够了
Python整数是大整数,所以这应该不会是问题。如果它们存储在内存中,并且您将每个字符串作为对象而不是文本进行比较,我建议使用id(string)
获取唯一整数。或者,如果要将它们存储在dict中,则可以使用带有一组匹配项的defaultdict并对其进行哈希:
>>> strings = 'a whole lot of strings which may share a hash'.split()
>>> storage = defaultdict(set)
>>> for s in strings:
... storage[hash(s)].add(s)
>>> storage[hash('a')]
{'a', 'a'}
具体如何实现这一点取决于您如何使用它们,但基本思想应该是可行的。如果您可以发布一个具体的示例,说明您正在尝试做什么,那么可能更容易给出更详细的答案。那么散列函数如何
In [130]: hash
Out[130]: <function hash>
In [131]: hash('foo')
Out[131]: -740391237
[130]中的:散列
出[130]:
在[131]中:散列('foo')
Out[131]:-740391237
不需要存储散列(除非您愿意):关键是对于值相等的对象,它们是相等的(尽管相反可能不是真的-无疑存在不相等的字符串或散列到相同值的其他对象;这就是散列的本质)
如果您知道密钥的范围(您可能知道),还可以使用一个完美的哈希函数生成器
完美哈希保证指定范围内的密钥与其哈希值具有双射关系。您可以使用其中一种算法创建长消息的加密语音摘要,然后将其用作字典密钥。使用SHA-256的示例:
import hashlib
...
key = hashlib.sha256(longMessage).digest()
与使用哈希(longMessage)相比,这种方法发生冲突的可能性要小得多
但是,这可能会带来巨大的开销。除非内存使用是一个大问题,否则我只会将原始字符串用作键。dict
是一个很好的解决方案。如果您有一种基于字符串ID生成唯一ID的方法,您可以将其作为自定义字符串类的哈希函数执行双重任务:
class ID_String(str):
cached_hash = None
def __hash__(self):
# custom hash code here
return custom_hash
def ID(self):
if self.cached_hash is None:
self.cached_hash = self.__hash__()
return self.cached_hash
为此,我使用了以下方法:
>>> from collections import defaultdict
>>> d = defaultdict(lambda: len(d))
>>> d["cats"]
0
>>> d["cars"]
1
>>> d["cats"]
0
id
只有在实习后才能用于此目的。比较两个对象的id
与比较是一样的。是的。这就是为什么我说作为对象而不是文本进行比较。实习当然是必要的,然后id会给出一个唯一的整数。感谢伟大的链接和建议,Marcin!碰撞是什么首先,我关心的是:我想使用我自己的哈希函数,扩展我对密钥结构的知识,但是为了处理冲突,我必须实现整个slots机制,而dict()免费提供给我,尽管它的内部散列可能更通用,因此不如我对特定字符串所做的有效。这对我不起作用,当我实际为两个字符串打印intern
时:featureVal是美分编码的特征值是4571865856 featureVal是数字槽编码的特征值ue是4571867200 featureVal是bn编码的特征值是4537878648 featureVal是沙特编码的特征值是4571865856
-请注意,cents
一词与saudi
的特征值完全相同。该行是print“featureVal is”,featureVal print“Encoded feature value is”,id(内部)(str(功能值编码(“utf-8”))