Índice de palabras múltiples de Python

index = {'Michael': [['mj.com',1], ['Nine.com',9],['i.com', 34]], / 'Jackson': [['One.com',4],['mj.com', 2],['Nine.com', 10], ['i.com', 45]], / 'Thriller' : [['Seven.com', 7], ['Ten.com',10], ['One.com', 5], ['mj.com',3]} # In this dictionary (index), for eg: 'KEYWORD': # [['THE LINK in which KEYWORD is present,'POSITION # of KEYWORD in the page specified by link']] 

por ejemplo: Michael está presente en MJ.com, NINE.com e i.com en las posiciones 1, 9, 34 de las páginas respectivas.

Por favor, ayúdeme con un procedimiento de python que toma el index y las KEYWORDS como entrada.

Cuando entro en 'MICHAEL' . El resultado debe ser:

 >>['mj.com', 'nine.com', 'i.com'] 

Cuando entro en 'MICHAEL JACKSON'. El resultado debe ser:

>>['mj.com', 'Nine.com']

como ‘ Michael' y ‘ Jackson' están presentes en 'mj.com' y 'nine.com' consecutivamente, es decir, en las posiciones (1,2) y (9,10) respectivamente. El resultado no debe mostrar 'i.com' a pesar de que contiene ambas PALABRAS CLAVE pero no se colocan consecutivamente.

Cuando entro en 'MICHAEL JACKSON THRILLER', el resultado debería ser

['mj.com']

como las 3 palabras 'MICHAEL', 'JACKSON', 'THRILLER' se colocan consecutivamente en 'mj.com' es decir, las posiciones (1, 2, 3) respectivamente.

Si ingreso 'THRILLER JACKSON' o 'THRILLER FEDERER', el resultado debería ser NONE .

Como nota al margen, Udacity Intro to CS cubre precisamente esta pregunta. Esto hace una serie de suposiciones acerca de las entradas apropiadas (esencialmente que nunca encuentra ninguna incorrecta).

 def lookup(index,KEYWORDS): kw = KEYWORDS.split() if len(kw) == 1: return [site[0] for site in index[kw[0]]] else: positions = {} result = [] kw = KEYWORDS.split() for kword in kw: for site in index[kword]: positions[(kword,site[0])]=site[1] for i in range(0,len(kw)-1): cur_urls = [site[0] for site in index[kw[i]]] next_urls = [site[0] for site in index[kw[i+1]]] if i == 0: result = cur_urls for url in cur_urls: if url in next_urls: if not (positions[kw[i+1],url]-positions[kw[i],url]) == 1: result.remove(url) else: if url in result: result.remove(url) return result 

utilizando conjuntos e intersecciones:

 def func(key,dic): keys=key.split() values=[set(y if i==0 else y if dic[x][y]-dic[keys[i-1]].get(y,-10000)==1 \ else None for y in dic[x]) for i,x in enumerate(keys)] sett=values[0] for y in values[1:]: sett &= y print(sett) index = {'Michael': {'mj.com':1,'Nine.com':9,'i.com':34}, 'Jackson':{'One.com':4,'mj.com':2,'Nine.com':10,'i.com':45}, 'Thriller' : {'Seven.com':7,'Ten.com':10,'One.com':5,'mj.com':3}} 

salida:

 >>> func("Michael",index) {'Nine.com', 'mj.com', 'i.com'} >>> func("Michael Jackson",index) {'Nine.com', 'mj.com'} >>> func("Michael Jackson Thriller",index) {'mj.com'} 

Primero, dado que su búsqueda parece ignorar el caso, debe escribir en mayúsculas (o en minúsculas) su índice.

 index = dict((key.upper(), val) for (key, val) in index.iteritems()) 

Ahora aquí hay un enfoque recursivo. Primero, la función de interfaz:

 def search(query): return [site for (site, pos) in search2(query.split())] 

La siguiente función hace el trabajo real. Si solo se da una palabra, devuelva la entrada en el índice para esta palabra; De lo contrario filtre para aquellos índices donde las posiciones coinciden.

 def search2(words): if len(words) == 1: return index[words[0]] else: return [(site1, pos1) for (site1, pos1) in index[words[0]] for (site2, pos2) in search2(words[1:]) if (site1 == site2 and pos1 == pos2-1)] 

Por supuesto, las cosas se complican un poco más si pos puede ser una lista de posiciones para cada sitio …