我正在尝试在Python中实现多图。每个记录都有三个字段。
序列号,名称,食物
1 John Apple
2 Bill Orange
3 Josh Apple
在这里,SerialNo
和Name
除了Food
之外不会重复。
我可以在哈希图中插入一个键,值并对其进行查询。但是,如何与三个价值观建立关系。我想像这样查询
SerialNo s where Food='Apple'
Name where Food='Apple'
Food where Name='Bill'
Get the all stored data (SerialNo, Name, Food)
我只能建立一个索引,但是如何对每个字段进行查询。
这是我要插入数据的哈希图,
class HashMap:
def __init__(self):
self.store = [None for _ in range(16)]
self.size = 0
def put(self, key, value):
p = Node(key, value)
key_hash = self._hash(key)
index = self._position(key_hash)
if not self.store[index]:
self.store[index] = [p]
self.size += 1
else:
list_at_index = self.store[index]
if p not in list_at_index:
list_at_index.append(p)
self.size += 1
else:
for i in list_at_index:
if i == p:
i.value = value
break
我不能使用dict
,我更喜欢从头开始构建函数以供学习。
答案 0 :(得分:0)
听起来您正在尝试实现数据库表。这是最自然地实现为一组命令。 (但是有些库的实现效率更高,例如sqlite和pandas)
table = {
dict(zip(('SerialNo', 'Name', 'Food'), row))
for row in [
(1, 'John', 'Apple'),
(2, 'Bill', 'Orange'),
(3, 'Josh', 'Apple'),
]
}
您可以将查询作为列表推导。
# SerialNo s where Food='Apple'
[row['Food'] for row in table if row['Food'] == 'Apple']
# Name where Food='Apple'
[row['Name'] for row in table if row['Food'] == 'Apple']
# Food where Name='Bill'
[row['Food'] for row in table if row['Name'] == 'Bill']
# Get the all stored data (SerialNo, Name, Food)
table
更复杂的查询是可能的。对于大型表,可以像数据库引擎一样通过预先创建外部索引来提高查询效率。将字典与查找键一起使用,并将它们指向表集中的行字典。
name_index = {row['Name']: row for row in table}
name_index['John'] # {'SerialNo': 1, 'Name': 'John', 'Food': 'Apple'}
您还可以尝试使用一组命名的元组作为表行,而不是使用字典来提高效率。这也使您可以将点符号用于单元格访问。
嗨,我不能使用dict。我更喜欢构建用于学习目的的功能。
好的,所以实现一个普通的哈希表,并使用它代替本地Python dict。如果您需要多个索引,请使用上述多个哈希表。
但是,我有重复的食品价值,该如何索引?
考虑使用该索引的查询将返回什么。是使用该食物的一组行,而不是单个行,对吗?这就是您用作在索引哈希表中查找的值的方法。
{food: {row for row in table if row['Food']==food}
for food in {row['Food'] for row in table}}
使用for循环,您可能可以更有效地做到这一点。
food_index = {}
for row in table:
food_index.setdefault(row['Food'], set()).add(row)
如果唯一索引还返回行集而不是单行,则可以简化逻辑。 (在这种情况下,该集合将只包含一行。)
name_index = {row['Name']: {row} for row in table}
我仍在使用字典来简洁地演示该方法,但是没有理由您不能自己实现所有这些功能。甚至可以通过函数调用内部的生成器表达式来实现理解,例如
{k:v for k, v in foo}
dict((k, v) for k, v in foo)
以上两行在功能上是等效的。当然,如果foo
已经包含对(例如zip
调用的结果),则可以简化为
dict(foo)
您可以使用自己的哈希表类代替dict
。
您的多图实现可以在初始化时创建和存储这些索引,并在向表中添加或删除行时适当地更新每个索引中的行集。更改行dict可能会使索引无效,因此使每行成为不可变的类型(如命名元组等)(如果需要,请自己实现)可能更合适。然后,更改表中的一行就是添加新行并删除旧行。