Mapa de hash en Python

144

Quiero implementar un HashMap en Python. Quiero pedirle a un usuario una entrada. dependiendo de su entrada, estoy recuperando información del HashMap. Si el usuario ingresa una clave de HashMap, me gustaría recuperar el valor correspondiente.

¿Cómo implemento esta funcionalidad en Python?

HashMap<String,String> streetno=new HashMap<String,String>();
   streetno.put("1", "Sachin Tendulkar");
   streetno.put("2", "Dravid");
   streetno.put("3","Sehwag");
   streetno.put("4","Laxman");
   streetno.put("5","Kohli")
Kiran Bhat
fuente

Respuestas:

246

El diccionario Python es un tipo incorporado que admite pares clave-valor.

streetno = {"1": "Sachin Tendulkar", "2": "Dravid", "3": "Sehwag", "4": "Laxman", "5": "Kohli"}

además de usar la palabra clave dict:

streetno = dict({"1": "Sachin Tendulkar", "2": "Dravid"}) 

o:

streetno = {}
streetno["1"] = "Sachin Tendulkar" 
Alan
fuente
11
El segundo ejemplo solo construye un dict de la misma manera que antes y luego lo copia. El otro uso dict, que sería más apropiado en este contexto, es dict(key1=value1, key2=value2, ...)que requiere las claves de las cadenas que también son identificadores válidos de Python (e internamente, esto también crea un diccionario).
Ah interesante, no me di cuenta de que las cadenas desnudas eran identificadores válidos.
Alan
No estoy seguro si te entiendo correctamente (¿qué son las "cuerdas desnudas"?), Pero creo que lo entendiste al revés. Su segundo ejemplo actualizado no es válido y nunca tuve la intención de decir algo así. La sintaxis de argumentos de palabras clave , que acepta solo identificadores desnudos, utiliza internamente un diccionario. El dictconstructor admite argumentos de palabras clave y funciona como def dict(**kwds): return kwdssi tuviera argumentos de palabras clave.
El segundo ejemplo genera un error de sintaxis. los nombres de variables no pueden comenzar con un número
Simon Bergot
Sí, parece un "mapa" y actúa como un "mapa". Pero la pregunta no es "Mapa en Python" sino "Mapa hash en Python": ¿Son los diccionarios un mapa hash (!)?
309963d8521805330a44bdcb3d87f3
27

Todo lo que quería (en el momento en que se hizo la pregunta originalmente) era una pista. Aquí hay una pista: en Python, puedes usar diccionarios .

Christian Neverdal
fuente
24

Está integrado para Python. Ver diccionarios .

Según su ejemplo:

streetno = {"1": "Sachine Tendulkar",
            "2": "Dravid",
            "3": "Sehwag",
            "4": "Laxman",
            "5": "Kohli" }

A continuación, puede acceder de la siguiente manera:

sachine = streetno["1"]

También vale la pena mencionar: puede usar cualquier tipo de datos no mutable como clave. Es decir, puede usar una tupla, un booleano o una cadena como clave.

Edwin
fuente
16
streetno = { 1 : "Sachin Tendulkar",
            2 : "Dravid",
            3 : "Sehwag",
            4 : "Laxman",
            5 : "Kohli" }

Y para recuperar valores:

name = streetno.get(3, "default value")

O

name = streetno[3]

Eso es usar números como teclas, poner comillas alrededor de los números para usar cadenas como teclas.

Totaam
fuente
14

Los mapas hash están integrados en Python, se llaman diccionarios :

streetno = {}                        #create a dictionary called streetno
streetno["1"] = "Sachin Tendulkar"   #assign value to key "1"

Uso:

"1" in streetno                      #check if key "1" is in streetno
streetno["1"]                        #get the value from key "1"

Consulte la documentación para obtener más información, por ejemplo, métodos integrados, etc. Son geniales y muy comunes en los programas de Python (como era de esperar).

relajarse
fuente
12

Aquí está la implementación del Hash Map usando python. Por simplicidad, el hash map tiene un tamaño fijo 16. Esto se puede cambiar fácilmente. Rehashing está fuera del alcance de este código.

class Node:
    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.next = None

class HashMap:
    def __init__(self):
        self.store = [None for _ in range(16)]
    def get(self, key):
        index = hash(key) & 15
        if self.store[index] is None:
            return None
        n = self.store[index]
        while True:
            if n.key == key:
                return n.value
            else:
                if n.next:
                    n = n.next
                else:
                    return None
    def put(self, key, value):
        nd = Node(key, value)
        index = hash(key) & 15
        n = self.store[index]
        if n is None:
            self.store[index] = nd
        else:
            if n.key == key:
                n.value = value
            else:
                while n.next:
                    if n.key == key:
                        n.value = value
                        return
                    else:
                        n = n.next
                n.next = nd

hm = HashMap()
hm.put("1", "sachin")
hm.put("2", "sehwag")
hm.put("3", "ganguly")
hm.put("4", "srinath")
hm.put("5", "kumble")
hm.put("6", "dhoni")
hm.put("7", "kohli")
hm.put("8", "pandya")
hm.put("9", "rohit")
hm.put("10", "dhawan")
hm.put("11", "shastri")
hm.put("12", "manjarekar")
hm.put("13", "gupta")
hm.put("14", "agarkar")
hm.put("15", "nehra")
hm.put("16", "gawaskar")
hm.put("17", "vengsarkar")
print(hm.get("1"))
print(hm.get("2"))
print(hm.get("3"))
print(hm.get("4"))
print(hm.get("5"))
print(hm.get("6"))
print(hm.get("7"))
print(hm.get("8"))
print(hm.get("9"))
print(hm.get("10"))
print(hm.get("11"))
print(hm.get("12"))
print(hm.get("13"))
print(hm.get("14"))
print(hm.get("15"))
print(hm.get("16"))
print(hm.get("17"))

Salida:

sachin
sehwag
ganguly
srinath
kumble
dhoni
kohli
pandya
rohit
dhawan
shastri
manjarekar
gupta
agarkar
nehra
gawaskar
vengsarkar
Vishwas Abhyankar
fuente
¡Creo que tu lógica es parcialmente correcta! hash(key) & 15, 73%15= 13pero es equivalente: 1001001 & 0001111 = 0001111es decir, 9y no 13, creo que usar mod es la operación correcta. ¡Corrígeme si estoy equivocado!
Anu
Sin embargo, ¿cómo iteras por la lista?
Petro
8
class HashMap:
    def __init__(self):
        self.size = 64
        self.map = [None] * self.size

    def _get_hash(self, key):
        hash = 0

        for char in str(key):
            hash += ord(char)
        return hash % self.size

    def add(self, key, value):
        key_hash = self._get_hash(key)
        key_value = [key, value]

        if self.map[key_hash] is None:
            self.map[key_hash] = list([key_value])
            return True
        else:
            for pair in self.map[key_hash]:
                if pair[0] == key:
                    pair[1] = value
                    return True
                else:
                    self.map[key_hash].append(list([key_value]))
                    return True

    def get(self, key):
        key_hash = self._get_hash(key)
        if self.map[key_hash] is not None:
            for pair in self.map[key_hash]: 
                if pair[0] == key:
                    return pair[1]
        return None

    def delete(self, key):
        key_hash = self._get_hash(key)

        if self.map[key_hash] is None :
            return False
        for i in range(0, len(self.map[key_hash])):
            if self.map[key_hash][i][0] == key:
                self.map[key_hash].pop(i)
                return True

    def print(self):

        print('---Phonebook---')
        for item in self.map:
            if item is not None:
                print(str(item))

h = HashMap()
krezaeim
fuente
7

Python Counter también es una buena opción en este caso:

from collections import Counter

counter = Counter(["Sachin Tendulkar", "Sachin Tendulkar", "other things"])

print(counter)

Esto devuelve un dict con el recuento de cada elemento en la lista:

Counter({'Sachin Tendulkar': 2, 'other things': 1})
Soldado de las sombras
fuente
1

En python usarías un diccionario.

Es un tipo muy importante en python y se usa con frecuencia.

Puedes crear uno fácilmente

name = {}

Los diccionarios tienen muchos métodos:

# add entries:
>>> name['first'] = 'John'
>>> name['second'] = 'Doe'
>>> name
{'first': 'John', 'second': 'Doe'}

# you can store all objects and datatypes as value in a dictionary
# as key you can use all objects and datatypes that are hashable
>>> name['list'] = ['list', 'inside', 'dict']
>>> name[1] = 1
>>> name
{'first': 'John', 'second': 'Doe', 1: 1, 'list': ['list', 'inside', 'dict']}

No puede influir en el orden de un dict.

Franco
fuente