usar unir llenar for ejemplo diccionarios diccionario con como cargar buscar arreglo python dictionary iteration intersection

unir - diccionarios python



Intersección de dos diccionarios en Python (6)

De acuerdo, aquí hay una versión generalizada del código anterior en Python3. Está optimizado para usar comprensiones y vistas dict del tipo set que son lo suficientemente rápidas.

La función intersecta muchos dictados arbitrarios y devuelve un dict con claves comunes y un conjunto de valores comunes para cada clave común:

def dict_intersect(*dicts): comm_keys = dicts[0].keys() for d in dicts[1:]: # intersect keys first comm_keys &= d.keys() # then build a result dict with nested comprehension result = {key:{d[key] for d in dicts} for key in comm_keys} return result

Ejemplo de uso:

a = {1: ''ba'', 2: ''boon'', 3: ''spam'', 4:''eggs''} b = {1: ''ham'', 2:''baboon'', 3: ''sausages''} c = {1: ''more eggs'', 3: ''cabbage''} res = dict_intersect(a, b, c) # Here is res (the order of values may vary) : # {1: {''ham'', ''more eggs'', ''ba''}, 3: {''spam'', ''sausages'', ''cabbage''}}

Aquí los valores dict deben ser hashable, si no lo son, simplemente puedes cambiar el paréntesis de conjuntos {} a list []:

result = {key:[d[key] for d in dicts] for key in comm_keys}

Estoy trabajando en un programa de búsqueda sobre un índice invertido. El índice en sí es un diccionario cuyas claves son términos y cuyos valores son en sí mismos diccionarios de documentos cortos, con números de identificación como claves y su contenido de texto como valores.

Para realizar una búsqueda ''Y'' de dos términos, necesito intersecar sus listas de publicaciones (diccionarios). ¿Cuál es una forma clara (no necesariamente inteligente) de hacer esto en Python? Empecé por intentarlo a lo largo de iter :

p1 = index[term1] p2 = index[term2] i1 = iter(p1) i2 = iter(p2) while ... # not sure of the ''iter != end ''syntax in this case ...


En Python 3, puedes usar

intersection = dict(dict1.items() & dict2.items()) union = dict(dict1.items() | dict2.items()) difference = dict(dict1.items() ^ dict2.items())


Puede calcular fácilmente la intersección de conjuntos, por lo tanto, cree conjuntos a partir de las claves y utilícelos para la intersección:

keys_a = set(dict_a.keys()) keys_b = set(dict_b.keys()) intersection = keys_a & keys_b # ''&'' operator is used for set intersection


Simplemente ajuste las instancias del diccionario con una clase simple que obtenga los dos valores que desea

class DictionaryIntersection(object): def __init__(self,dictA,dictB): self.dictA = dictA self.dictB = dictB def __getitem__(self,attr): if attr not in self.dictA or attr not in self.dictB: raise KeyError(''Not in both dictionaries,key: %s'' % attr) return self.dictA[attr],self.dictB[attr] x = {''foo'' : 5, ''bar'' :6} y = {''bar'' : ''meow'' , ''qux'' : 8} z = DictionaryIntersection(x,y) print z[''bar'']


Un hecho poco conocido es que no necesita construir set para hacer esto:

En Python 2:

In [78]: d1 = {''a'': 1, ''b'': 2} In [79]: d2 = {''b'': 2, ''c'': 3} In [80]: d1.viewkeys() & d2.viewkeys() Out[80]: {''b''}

En Python 3, reemplace las keys viewkeys con las keys ; lo mismo se aplica a viewvalues y viewitems .

De la documentación de viewitems :

In [113]: d1.viewitems?? Type: builtin_function_or_method String Form:<built-in method viewitems of dict object at 0x64a61b0> Docstring: D.viewitems() -> a set-like object providing a view on D''s items

Para dict s más grandes, esto también es un poco más rápido que construir set y luego intersecarlos:

In [122]: d1 = {i: rand() for i in range(10000)} In [123]: d2 = {i: rand() for i in range(10000)} In [124]: timeit d1.viewkeys() & d2.viewkeys() 1000 loops, best of 3: 714 µs per loop In [125]: %%timeit s1 = set(d1) s2 = set(d2) res = s1 & s2 1000 loops, best of 3: 805 µs per loop For smaller `dict`s `set` construction is faster: In [126]: d1 = {''a'': 1, ''b'': 2} In [127]: d2 = {''b'': 2, ''c'': 3} In [128]: timeit d1.viewkeys() & d2.viewkeys() 1000000 loops, best of 3: 591 ns per loop In [129]: %%timeit s1 = set(d1) s2 = set(d2) res = s1 & s2 1000000 loops, best of 3: 477 ns per loop

Estamos comparando nanosegundos aquí, que pueden o no importarle. En cualquier caso, recuperas un set , por lo que usar las keys viewkeys / keys elimina un poco el desorden.


In [1]: d1 = {''a'':1, ''b'':4, ''f'':3} In [2]: d2 = {''a'':1, ''b'':4, ''d'':2} In [3]: d = {x:d1[x] for x in d1 if x in d2} In [4]: d Out[4]: {''a'': 1, ''b'': 4}