在Python中实现多图

时间:2018-10-21 03:24:05

标签: python algorithm data-structures hashmap

我正在尝试在Python中实现多图。每个记录都有三个字段。

序列号,名称,食物

1 John Apple
2 Bill Orange
3 Josh Apple

在这里,SerialNoName除了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,我更喜欢从头开始构建函数以供学习。

1 个答案:

答案 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可能会使索引无效,因此使每行成为不可变的类型(如命名元组等)(如果需要,请自己实现)可能更合适。然后,更改表中的一行就是添加新行并删除旧行。