在Python中将唯一字符串映射为整数

在Python中将唯一字符串映射为整数,python,Python,比如说,我有一份清单 L=['apple','bat','apple','car','pet','bat'] 我想把它转换成 Lnew=[1,2,1,3,4,2] 每个唯一的字符串都与一个数字相关联 我有一个使用hashmap的java解决方案,但我不知道如何在python中使用hashmap。 请提供帮助。您可以使用地图词典: d = {'apple':1, 'bat':2, 'car':3, 'pet':4} L = ['apple','bat','apple','car','pet','b

比如说,我有一份清单
L=['apple','bat','apple','car','pet','bat']

我想把它转换成
Lnew=[1,2,1,3,4,2]

每个唯一的字符串都与一个数字相关联

我有一个使用
hashmap
的java解决方案,但我不知道如何在python中使用
hashmap

请提供帮助。

您可以使用地图词典:

d = {'apple':1, 'bat':2, 'car':3, 'pet':4}
L = ['apple','bat','apple','car','pet','bat']
[d[x] for x in L] # [1, 2, 1, 3, 4, 2]
对于自动创建地图字典,您可以使用带有计数器的
defaultdict(int)

from collections import defaultdict
d = defaultdict(int)
co = 1
for x in L:
    if not d[x]:
        d[x] = co
        co+=1
d # defaultdict(<class 'int'>, {'pet': 4, 'bat': 2, 'apple': 1, 'car': 3})
从集合导入defaultdict
d=默认dict(int)
co=1
对于L中的x:
如果不是d[x]:
d[x]=co
co+=1
d#defaultdict(,{'pet':4,'bat':2,'apple':1,'car':3})

或者正如@Stuart所提到的,您可以使用
d=dict(zip(set(L),range(len(L)))
来创建字典您也可以使用Python中的hashmap,但我们称之为
dict

Lnew = []
for s in L:
    Lnew.append(hash(s))  # hash(x) returns a unique int based on string
>>> L = ['apple','bat','apple','car','pet','bat']
>>> idx = 1
>>> seen_first = {}
>>>
>>> for word in L:
...     if word not in seen_first:
...         seen_first[word] = idx
...         idx += 1
... 
>>> [seen_first[word] for word in L]
[1, 2, 1, 3, 4, 2]

下面是一个快速解决方案:

l = ['apple','bat','apple','car','pet','bat']
创建将所有唯一字符串映射为整数的dict:

d = dict([(y,x+1) for x,y in enumerate(sorted(set(l)))])
将原始列表中的每个字符串映射到其各自的整数:

print [d[x] for x in l]
# [1, 2, 1, 3, 4, 2]
您可以尝试:

>>> L = ['apple','bat','apple','car','pet','bat']
>>> l_dict = dict(zip(set(L), range(len(L))))
>>> print l_dict
{'pet': 0, 'car': 1, 'bat': 2, 'apple': 3}
>>> [l_dict[x] for x in L]
[3, 2, 3, 1, 0, 2]


您尝试了什么?python中的Dict的工作原理如下hashmap@RaminNietzsche,我不能代表Java的hashmap,但Python的dicts没有给出提问者想要的整数索引,特别是按字母顺序排序的索引(这不是特别要求的,但在他们想要的输出中很明显)。你如何计算出与字符串关联的数字?@RaminNietzsche,不过,你的想法是对的,你可以使用dict以这种方式创建映射:
d={k:v代表v,k在enumerate(sorted(set(L))}
然后
Lnew=[d[x]对于L中的x
。我有很多字符串。因此在代码中手动复制是不可行的。@Mustafa我编辑了关于如何自动创建词典的答案。您可以使用
d=dict(zip(set(L),range(len(L)))自动创建映射
@Mustafa您需要在某个地方定义字符串和整数之间的映射?当然,如果您希望第一个单词只包含数字1Code,而不是所需的输出,
list.index
是O(n)每调用一次。不幸的是,这可以在O(n)中完成。
list(set(sorted(L)))
[x.index(v)+1…
来获得提问者想要的输出。我只想添加
枚举(set(sorted(l))
,因为提问者没有指定字母排序,但他们想要的输出有它。另外,你可以使用dict理解:
d={k:v代表v,k代表枚举(sorted(set(l))}
这是否有效取决于OP是否只需要描述的“一个数字”,或者实际上需要输出中显示的第一个索引+1;也可以使用
dict
理解
[3,2,3,1,0,2]
不是所需的结果,我是否遗漏了什么?回答者没有对列表进行排序或对映射进行1索引。下面将使用相同的方法并给出相同的输出:
d={k:v+1表示v,k表示枚举(排序(集合(L))}
,然后
Lnew=[d[x]表示L中的x]
+1以获得最明显和最明智的答案;但是
{x:len(L)-i for i,x in enumerate(L[:-1])}
如何构建dict@Chris_Rands我刚刚意识到OP不想按索引+1进行搜索,而是给第一个唯一的单词加上数字1,给第二个唯一的单词加上数字2,依此类推。(我相应地编辑了我的答案。)我现在认为他们真正想要的(基于最上面的答案)是这个,但坦率地说,这个问题并不清楚,应该结束IMO@Chris_Rands是的,我现在很困惑。从这个问题来看,我认为他们在寻找基于1的整数,而不是很长的整数
hash() GiVS.考虑提供对代码的解释<代码> hash 不为每个字符串返回唯一的<代码> int 。哈希冲突。如果你解释这是有损编码(映射不保证是1:1,并且可能不是完全可逆的),那么这里的一般方法就很好了。。更大的问题是,内置的哈希函数在任何两次运行中都不一致。使用blake2s的hashlib并减少到int会更好。
>>> L = ['apple','bat','apple','car','pet','bat']
>>> l_dict = dict(zip(set(L), range(len(L))))
>>> print l_dict
{'pet': 0, 'car': 1, 'bat': 2, 'apple': 3}
>>> [l_dict[x] for x in L]
[3, 2, 3, 1, 0, 2]