Python 幂等散列关联
我有一些名字:Python 幂等散列关联,python,hash,Python,Hash,我有一些名字:[“詹姆斯”、“约翰”、“克里格”]和一些颜色:[“红”、“绿”、“蓝”、“黄”]。我想使用一些散列函数将名称映射到颜色:f(name)->color。这个关联是幂等的。例如,如果在原始列表中,f(James)->Red,则在我向其各自的列表中添加名称或颜色后,f(James)仍保持Red 例如: 清单1: ["James", "John", "Krieg"] and ["Red", "Green", "Blue", "Yellow"]: f(James) -> R
[“詹姆斯”、“约翰”、“克里格”]
和一些颜色:[“红”、“绿”、“蓝”、“黄”]
。我想使用一些散列函数将名称映射到颜色:f(name)->color
。这个关联是幂等的。例如,如果在原始列表中,f(James)->Red
,则在我向其各自的列表中添加名称或颜色后,f(James)
仍保持Red
例如:
清单1:
["James", "John", "Krieg"] and ["Red", "Green", "Blue", "Yellow"]:
f(James) -> Red
f(John) -> Yellow
f(Krieg) -> Yellow
清单2:
["James", "John", "Krieg", "Sarah"] and ["Red", "Green", "Blue", "Yellow", "Black"]:
(added "Sarah" and "Black")
f(James) -> Red
f(John) -> Yellow
f(Krieg) -> Yellow
f(Sarah) -> Green
哈希函数的细节并不重要,只要它尝试一致性。我有这个问题,因为我有一个向用户显示的名称列表,随着该列表的增长,我希望以前输入的名称的颜色关联相同(因此用户保留名称/颜色关联)。我意识到,如果我提前指定颜色列表,这不会是一个问题
因此,现在只是出于好奇——有没有散列函数在没有持久性的情况下,不会随着输入/输出大小的增长而改变以前关联的值?很抱歉前面的混淆。您说得对,您只需要将关联存储在内存中。您需要的是这样一个可变的关联集。在python中,这是一个字典:
>>> assocs = dict(zip(['James', 'John', 'Krieg', 'Sarah'], ['Red', 'Green', 'Blue', 'Yellow']))
>>> assocs['Sarah']
'Yellow'
>>> assocs['Sarah'] = 'Black'
>>> assocs['Sarah']
'Black'
编辑
如果您总是有两个列表,并且它们总是有序的,那么为什么不使用列表索引来“存储”映射:
>>> names = ['James', 'John', 'Krieg', 'Sarah']
>>> colors = ['Red', 'Green', 'Blue', 'Yellow']
>>> def finmap(name):
... i = names.index(name)
... if i < len(colors):
... return colors[i]
... else:
... print 'all the colors have been assigned'
...
>>姓名=['James','John','Krieg','Sarah']
>>>颜色=[“红色”、“绿色”、“蓝色”、“黄色”]
>>>def finmap(名称):
... i=名称。索引(名称)
... 如果i
希望这有助于您是对的,您只需要将关联存储在内存中。您需要的是这样一个可变的关联集。在python中,这是一个字典:
>>> assocs = dict(zip(['James', 'John', 'Krieg', 'Sarah'], ['Red', 'Green', 'Blue', 'Yellow']))
>>> assocs['Sarah']
'Yellow'
>>> assocs['Sarah'] = 'Black'
>>> assocs['Sarah']
'Black'
编辑
如果您总是有两个列表,并且它们总是有序的,那么为什么不使用列表索引来“存储”映射:
>>> names = ['James', 'John', 'Krieg', 'Sarah']
>>> colors = ['Red', 'Green', 'Blue', 'Yellow']
>>> def finmap(name):
... i = names.index(name)
... if i < len(colors):
... return colors[i]
... else:
... print 'all the colors have been assigned'
...
>>姓名=['James','John','Krieg','Sarah']
>>>颜色=[“红色”、“绿色”、“蓝色”、“黄色”]
>>>def finmap(名称):
... i=名称。索引(名称)
... 如果i
希望这会有所帮助我不完全清楚你所说的“一种快速的方法”是什么意思,但我认为幂等字典可能会有所帮助。例如:
##!/usr/bin/env python
# coding: utf-8
class idempotent_dict(dict):
def __setitem__(self, key, value):
if key in self:
return
super(idempotent_dict, self).__setitem__(key, value)
if __name__ == '__main__':
d = idempotent_dict()
d['James'] = 'Red'
d['John'] = 'Yellow'
d['Krieg'] = 'Yellow'
print d
d['James'] = 'Black'
d['John'] = 'Red'
d['Sarah'] = 'Green'
print d
这张照片是:
{'James': 'Red', 'John': 'Yellow', 'Krieg': 'Yellow'}
{'Sarah': 'Green', 'James': 'Red', 'John': 'Yellow', 'Krieg': 'Yellow'}`
我不完全清楚你所说的“一种快速的方法”是什么意思,但我认为一本幂等字典可能会有所帮助。例如:
##!/usr/bin/env python
# coding: utf-8
class idempotent_dict(dict):
def __setitem__(self, key, value):
if key in self:
return
super(idempotent_dict, self).__setitem__(key, value)
if __name__ == '__main__':
d = idempotent_dict()
d['James'] = 'Red'
d['John'] = 'Yellow'
d['Krieg'] = 'Yellow'
print d
d['James'] = 'Black'
d['John'] = 'Red'
d['Sarah'] = 'Green'
print d
这张照片是:
{'James': 'Red', 'John': 'Yellow', 'Krieg': 'Yellow'}
{'Sarah': 'Green', 'James': 'Red', 'John': 'Yellow', 'Krieg': 'Yellow'}`
如果我理解您的问题,您需要一个对象,它将接受一个键列表和一个值列表(任意长度或无长度),并返回一个字典,该字典始终具有相同的值,而不考虑任何添加
>>> class ListOMatic(object):
def __init__(self):
self.people = []
self.colors = []
def idpt(self, people=[], colors=[]):
for p in people:
if not p in self.people:
self.people.append(p)
for c in colors:
if not c in self.colors:
self.colors.append(c)
return dict(zip(self.people, self.colors))
>>> lom = ListOMatic()
>>> people = ['James', 'John', 'Krieg']
>>> colors = ['Red', 'Green', 'Blue', 'Yellow']
>>> # populate it with our initial values and show that we can pull values out.
>>> print (lom.idpt(people, colors))
{'James': 'Red', 'John': 'Green', 'Krieg': 'Blue'}
>>> print (lom.idpt())
{'James': 'Red', 'John': 'Green', 'Krieg': 'Blue'}
>>> print (lom.idpt()["James"])
Red
>>> # add some colors but no names.
>>> print (lom.idpt([],["Purple", "Mauve"]))
{'James': 'Red', 'John': 'Green', 'Krieg': 'Blue'}
>>> print (lom.idpt())
{'James': 'Red', 'John': 'Green', 'Krieg': 'Blue'}
>>> # add a name and show that it "picks up" the first available color
>>> print (lom.idpt(["Sarah"],[]))
{'Sarah': 'Yellow', 'James': 'Red', 'John': 'Green', 'Krieg': 'Blue'}
>>> print (lom.idpt(["Victor", "Charlie"],["Puce"]))
{'Sarah': 'Yellow', 'James': 'Red', 'Charlie': 'Mauve', 'John': 'Green', 'Krieg': 'Blue', 'Victor': 'Purple'}
>>> print (lom.idpt())
{'Sarah': 'Yellow', 'James': 'Red', 'Charlie': 'Mauve', 'John': 'Green', 'Krieg': 'Blue', 'Victor': 'Purple'}
>>> print (lom.idpt()["Sarah"])
Yellow
>>>
希望这就是你所说的“在飞行中”的意思 如果我理解您的问题,您需要一个对象,该对象将获取一个键列表和一个值列表(任意长度或无长度),并返回一个字典,该字典始终具有相同的值,而不考虑任何添加
>>> class ListOMatic(object):
def __init__(self):
self.people = []
self.colors = []
def idpt(self, people=[], colors=[]):
for p in people:
if not p in self.people:
self.people.append(p)
for c in colors:
if not c in self.colors:
self.colors.append(c)
return dict(zip(self.people, self.colors))
>>> lom = ListOMatic()
>>> people = ['James', 'John', 'Krieg']
>>> colors = ['Red', 'Green', 'Blue', 'Yellow']
>>> # populate it with our initial values and show that we can pull values out.
>>> print (lom.idpt(people, colors))
{'James': 'Red', 'John': 'Green', 'Krieg': 'Blue'}
>>> print (lom.idpt())
{'James': 'Red', 'John': 'Green', 'Krieg': 'Blue'}
>>> print (lom.idpt()["James"])
Red
>>> # add some colors but no names.
>>> print (lom.idpt([],["Purple", "Mauve"]))
{'James': 'Red', 'John': 'Green', 'Krieg': 'Blue'}
>>> print (lom.idpt())
{'James': 'Red', 'John': 'Green', 'Krieg': 'Blue'}
>>> # add a name and show that it "picks up" the first available color
>>> print (lom.idpt(["Sarah"],[]))
{'Sarah': 'Yellow', 'James': 'Red', 'John': 'Green', 'Krieg': 'Blue'}
>>> print (lom.idpt(["Victor", "Charlie"],["Puce"]))
{'Sarah': 'Yellow', 'James': 'Red', 'Charlie': 'Mauve', 'John': 'Green', 'Krieg': 'Blue', 'Victor': 'Purple'}
>>> print (lom.idpt())
{'Sarah': 'Yellow', 'James': 'Red', 'Charlie': 'Mauve', 'John': 'Green', 'Krieg': 'Blue', 'Victor': 'Purple'}
>>> print (lom.idpt()["Sarah"])
Yellow
>>>
希望这就是你所说的“在飞行中”的意思 我要说的是,如果不依靠持久性,这种事情是不存在的 我们可以根据列表位置排除任何映射。让我们从N个名称和1种颜色开始——这意味着所有名称都映射到一种颜色。如果我们以后有N个名称和M种颜色,除非我们能够存储哪N个名称映射到第一种颜色,否则就无法实现这一点 同样,我们可以根据名称/颜色的值排除任何内容。假设我们有一个函数f(name,color),它提供了一个分数,根据这个分数来决定一个名字的最佳颜色。如果F(bob,绿色)>F(bob,红色),那么当我们的列表从
[bob],[red]
到[bob],[green,red]
时,我们会得到一个不同的映射
您可以找到一些退化的解决方案,这些解决方案不显式地“保存每个关联”,但仍然保持足够的状态以重新创建计算。充其量,这些存储的数据与存储映射的数据一样多。在最坏的情况下,他们会储存更多
幂等式的使用表明你最初的问题可能是抽象的好奇心。如果有一个特定的、实际的、您正试图解决的问题,对这个问题进行更具体的解释会有所帮助。我要说的是,如果不依靠持久性,这种事情是不存在的 我们可以根据列表位置排除任何映射。让我们从N个名称和1种颜色开始——这意味着所有名称都映射到一种颜色。如果我们以后有N个名称和M种颜色,除非我们能够存储哪N个名称映射到第一种颜色,否则就无法实现这一点 同样,我们可以根据名称/颜色的值排除任何内容。假设我们有一个函数f(name,color),它提供了一个分数,根据这个分数来决定一个名字的最佳颜色。如果F(bob,绿色)>F(bob,红色),那么当我们的列表从
[bob],[red]
到[bob],[green,red]
时,我们会得到一个不同的映射
您可以找到一些退化的解决方案,这些解决方案不显式地“保存每个关联”,但仍然保持足够的状态以重新创建计算。充其量,这些存储的数据与存储映射的数据一样多。在最坏的情况下,他们会储存更多
幂等式的使用表明你最初的问题可能是抽象的好奇心。如果有一个特定的、实际的、你正试图解决的问题,对这个问题进行更具体的解释会有所帮助。经过一番愚蠢的思考,我相信肖恩·麦克斯的观点是正确的:如果没有“坚持”,你不可能得到你想要的东西(但请参见下文**)。问题是,如果您不允许“持久性”,那么您可以将多个键映射到同一个值,也可以