简体   繁体   中英

Combining Keys in Dictionary into tuples in a list

I'm looking for a solution to search keys in a dictionary according to a list as value, and later append the keys to a list of tuples. I'm able to search for the correct keys but can't find a way to build the list I'm expecting. Appreciate for kind help.

As below, I'd like to find all keys in d which has a value equals to the element in the list l , and further put all searched keys into a list of tuples as shown in expected output.

d = {'acutrar': 'acutrar',
 'aguosa': 'aguoso',
 'capitalizareis': 'capitalizar',
 'conocerán': 'conocer',
 'conociéremos': 'conocer',
 'conocían': 'conocer',
 'conocías': 'conocer',
 'conozcas': 'conocer',
 'pales': 'palar',
 'planeareis': 'planear',
 'planearás': 'planear',
 'planeasteis': 'planear',
 'planeáramos': 'planear'}

l = ['conocer', 'NOT FOUND', 'NOT FOUND', 'planear']

for word in l:
    for (x,y) in d.items():
        if y == word:
            print(word, x) #I can only search for the keys but don't know how to build that list of tuples

Expected Output:

[('conocerán','conocías','conozcas','conocían','conociéremos'),('NOT FOUND'),('NOT FOUND'),('planeáramos','planeareis','planearás','planeasteis')]

Why don't transform the dictionary into a more suitable/convenient structure and perform the O(1) lookups by key instead of looping over all of the items and searching for the value:

from collections import defaultdict

d = {'acutrar': 'acutrar',
 'aguosa': 'aguoso',
 'capitalizareis': 'capitalizar',
 'conocerán': 'conocer',
 'conociéremos': 'conocer',
 'conocían': 'conocer',
 'conocías': 'conocer',
 'conozcas': 'conocer',
 'pales': 'palar',
 'planeareis': 'planear',
 'planearás': 'planear',
 'planeasteis': 'planear',
 'planeáramos': 'planear'}


t = defaultdict(list)
for key, value in d.items():
    t[value].append(key)

l = ['conocer', 'NOT FOUND', 'NOT FOUND', 'planear']

print([t.get(item, [item]) for item in l])

Prints:

[
    ['conozcas', 'conociéremos', 'conocías', 'conocerán', 'conocían'], 
    ['NOT FOUND'], 
    ['NOT FOUND'], 
    ['planeáramos', 'planearás', 'planeareis', 'planeasteis']
]

Your result is surprisingly a blend of keys and values.

A more homogeneous solution can be obtained by

[tuple(k for (k,v) in d.items() if v == w) for w in l]  

for

[('conocías', 'conozcas', 'conociéremos', 'conocerán', 'conocían'),
 (),
 (),
 ('planeareis', 'planeáramos', 'planeasteis', 'planearás')]

or :

{w:tuple(k for (k,v) in d.items() if v == w) for w in l}

for

{'conocer': ('conocías', 'conozcas', 'conociéremos', 'conocerán', 'conocían'),
 'NOT FOUND': (),
 'planear': ('planeareis', 'planeáramos', 'planeasteis', 'planearás')}

To get your expected output, you can build the list of tuples like this:

for word in l:
    hits = tuple()
    for (x,y) in d.items():
        if y == word:
            hits += (x,)
    if not hits:
        hits = ('NOT FOUND',)
    results.append(hits)

print(results)

First no need to iterate on the list of searched values IMO.

You could just do:

final = []

for k, v in d.items():
    if v in l:
        final.append(k)
final = tuple(final)

But you could even simplify it via a list comprehension as below:

final = tuple(k for k, v in d.items() if v in l)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM