简体   繁体   中英

fast way to return the key based on dictionary value in python

I have two dictionaries:

dict1 = agent_id:agent_email
dict2 = user_id:agent_id

I want to create a dictionary:

agent_id: list of user_ids associated with agent_id

How do I search dict2 for each agent_id from dict1 and return the associated key? I've been told that creating a list of keys and then searching is very slow. Is there a faster way?

The question suggested as a dupe does not tell me what I'd like to know. I'm trying to search all the values without creating a separate list. Also, once I have the value, how to I get the corresponding key?

EDIT All the information I need is in dict2. The question is how do I get at it. Each agent_id is associated with multiple user_id's. I want to create a dict that looks like this:

{agent_id_1:(user_id_1, user_id_2, user_id_45), agent_id_2:(user_id_987), agent_id_3:(user_id_10, user_id_67)...etc}

based on one of the answers, I'm looking into created a 'reverse dict'. I'm don't really understand this yet, as the values in dict2 (the agent_ids) are not unique. Is this the way to go?

If the values are unique (ie no repetitions, which I assume is so, from 'agent_id'), the easiest way is to maintain two dictionaries. The original one, and a second, where the keys are the values of the first, and its values are the indices of the first. This way lookup would be near-instant (only the time of the creation of the hash).

In case of repetitions in the values, little can be done but search. Again, it would be still faster if you maintain a tree structure with the values, and point back to the keys.

Let's start giving your dicts somewhat more descriptive names:

agent_id_to_email = agent_id: agent_email
user_to_agent_id = user_id: agent_id

Now, you want all user_id s from user_to_agent_id such that the agent_id is in a valid key in agent_id_to_email .

Straightforward iterate and lookup approach

Time complexity: Approximately linear in the size of user_to_agent_id .

for user_id in (user_id
    for user_id, agent_id in user_to_agent_id.iteritems()
    if agent_id in agent_id_to_email
):
     # do something

This is time-linear in len(user_to_agent_id) since we iterate over all its items. The agent_id in agent_id_to_email lookup should be approximately constant ( dict s are hash tables) or at worst O(nx ln(n)) . Since both dictionaries seem to be roughly the same size, it does not matter if n is over user_to_agent_id or agent_id_to_email . If agent_id_to_email is small in comparison to user_to_agent_id the reverse dictionary approach becomes more efficient, but as it stands that is as good as it gets.

Note also that set intersection seems to have an O(N) computational lower bound .

Using an answer from this SO question [link] , i've gone with the following code:

def dbwInvUserIdAgentId(dbwUserWithAgentD):
""" return dict of agents: user_id; only agents with 
    users and only one use per agent
    so this inverts the dict
    arguments:
            dbwUserWithAgentD =    dict of pure user_id: agent: id"""

    return {v:k for k, v in dbwUserWithAgentD.iteritems()}


def dbwAgentUserIdsListD(dbwInvUserIdAgentId, dbwUserWithAgentD):
    return_dict = {}
    for agent_id in dbwInvUserIdAgentId:
        temp_list = []
        for k, v in dbwUserWithAgentD.iteritems():
            if agent_id == v:
                temp_list.append(k)
        return_dict[agent_id] = temp_list
    return return_dict

can someone with a cs background tell me how efficient this is? Is there a better way? I'm having a hell of a time trying to apply what the other answers are saying. I think I probably didn't ask the question all that well.

Regardless, thank you very much for the answers.

Try this.

 for key1, val1 in dict1.iteritems():
        for key2,val2 in dict2.iteritems():
            if key1 == val2:
                print key2

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