Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中基于字典值返回键的快速方法_Python_Python 2.7 - Fatal编程技术网

python中基于字典值返回键的快速方法

python中基于字典值返回键的快速方法,python,python-2.7,Python,Python 2.7,我有两本字典: dict1 = agent_id:agent_email dict2 = user_id:agent_id 我想创建一个字典: agent_id: list of user_ids associated with agent_id 如何从dict1中搜索dict2中的每个代理id并返回关联的密钥?有人告诉我,创建一个键列表,然后进行搜索是非常缓慢的。有没有更快的办法 这个被当作傻瓜提的问题并没有告诉我我想知道什么。我正在尝试搜索所有值,而不创建单独的列表。还有,一旦我有了值,

我有两本字典:

dict1 = agent_id:agent_email
dict2 = user_id:agent_id
我想创建一个字典:

agent_id: list of user_ids associated with agent_id
如何从dict1中搜索dict2中的每个代理id并返回关联的密钥?有人告诉我,创建一个键列表,然后进行搜索是非常缓慢的。有没有更快的办法

这个被当作傻瓜提的问题并没有告诉我我想知道什么。我正在尝试搜索所有值,而不创建单独的列表。还有,一旦我有了值,我如何获得相应的键

编辑 我需要的所有信息都在第2条中。问题是我如何做到这一点。每个代理id都与多个用户id相关联。我想创建一个如下所示的dict:

{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}
根据其中一个答案,我正在研究创建一个“反向dict”。我还不太明白这一点,因为dict2(代理ID)中的值不是唯一的。这是要走的路吗?

试试这个

 for key1, val1 in dict1.iteritems():
        for key2,val2 in dict2.iteritems():
            if key1 == val2:
                print key2
如果这些值是唯一的(即,从“agent_id”开始,我假设没有重复),最简单的方法是维护两个字典。原始的一个和第二个,其中键是第一个的值,其值是第一个的索引。这种方式的查找几乎是即时的(仅在创建哈希时)


如果值中出现重复,除了搜索外,几乎无法执行其他操作。同样,如果您使用值维护一个树状结构,并指向键,则速度会更快。

让我们开始为您的dict命名一些更具描述性的名称:

agent_id_to_email = agent_id: agent_email
user_to_agent_id = user_id: agent_id
现在,您需要所有
user\u id
s从
user\u到\u agent\u id
,以便
agent\u id
位于
agent\u id\u to\u email
中的有效密钥中

直接迭代和查找方法

时间复杂度:用户到代理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
这在
len(user\u to\u agent\u id)
中是时间线性的,因为我们迭代了它的所有项。代理id to_电子邮件查找中的
代理id应该是近似恒定的(
dict
s是哈希表),或者在最坏的情况下
O(nx ln(n))
。由于这两个词典的大小似乎大致相同,所以无论
n
是否超过
user\u to\u agent\u id
agent\u id\u to\u email
。如果与
user\u-to\u-agent\u-id
相比
agent\u-to\u-email
较小,则反向字典方法会更有效,但就目前情况而言,这是最好的方法


另请注意,集合交叉点似乎有一个
O(N)

使用此SO问题的答案,我使用以下代码:

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
有cs背景的人能告诉我这有多有效吗?有更好的办法吗?我花了很长时间试图应用其他答案所说的。我想我可能问得不太好


不管怎样,非常感谢您的回答。

两个dict的大小是否可能重复?(即,预期的优化是否重要?哪个是较大的dict?)多久执行一次查找?@dhke dict较大。每人超过10000人,而且还在增长。速度很重要。在重复的情况下,您可以使用
值:set(key)
dict进行反向查找。此解决方案的优点是不消耗额外空间。不幸的是,它的时间复杂度为O(n²)——对于大型dict来说,它变得非常慢。如果我们首先构建一个反向dict(O(n)空间和时间复杂度),那么获得一个所有匹配项的列表只需要花费O(n)时间复杂度,这给了我们O(n)总体。我估计反向dict方法会更快,即使dict每个只包含20个左右的元素。@amon什么是反向dict方法?反向映射概念:map={a':1,'b':2}反向映射={1:'a',2:'b'}这可以作为反向映射={val:key for key,val in map.items()}假设字典查找是固定时间,这只剩下for循环的时间
dbwAgentUserIdsListD()
嵌套两个循环,因此为O(n²)。另请注意,当原始映射不是1:1时,
dbwInvUserIdAgentId()
会失败。@dhke非常感谢您对这个问题的关注。正在反转的dict(dbwUserWithAgentD)绝对不是1:1。每个代理id都有许多与其关联的用户id。因此,我将反转视为排序过滤器,因此产生的反转将有一个完整的代理ID列表,我可以使用它来创建所需的dict。希望这是有意义的。我很想知道我哪里出了问题
dbwInvUserIdAgentId
具有最后一个键。把
{a':1,'b':1}
放进去,你会得到
{1:'b'}
或者
{1:'a'}
,这取决于原始dict的迭代顺序(未定义)。所以,是的,你得到了一个过滤器,但是一个行为未定义的过滤器。