【问题标题】:Comparing keys of one dictionary to another dictionary with a list of values将一个字典的键与具有值列表的另一个字典进行比较
【发布时间】:2013-11-06 00:38:17
【问题描述】:

我有一本字典,其中包含不同数量项目的值列表。 我想将此字典 (dict1) 的值与另一个 (dict2) 的键进行比较,如果它们匹配,则打印 dict1 匹配组件的键和值,以及 dict2 的值。 这两个字典都非常大,目前这花费的时间太长了,您可以从这个基本脚本中猜到。

dict1 = {boys:[tom,jon],girls:[suzy]}

dict2 = {suzy:paper-stapler-extraordinaire,jon:paper-shredderoligist,tom:garbage-specialist}

输出:

    boys \t tom \t garbage-specialist

    boys \t jon \t paper-shredderoligist  etc.....

for k,v in dict2.items():

    for key,value in dict1.items():
         if k in value[0]:
             print str(key)+"\t"+str(value[0])+"\t"+v
         if len(value)>1:
             if k in value[1]:
                 print str(key)+"\t"+str(value[0])+"\t"+v

有人可以建议一种更节省内存的方法吗?也许是列表理解? 这一直没有工作... a = [k for k in dict2 if k in dict]

【问题讨论】:

  • 如果您使用 Python 2.x,请使用 iteritems 而不是 items
  • 这真的会影响速度吗?
  • dict.items 返回将项目复制为列表,而 dict.iteritems 返回一个迭代器; dict.iteritems 内存效率更高。
  • 您能否提供一个输入-输出示例,以便我们轻松帮助您?
  • 使用 dict.items 仍然需要几个小时。它可能在我的代码的上游,但那部分只是制作字典

标签: python list dictionary list-comprehension


【解决方案1】:
for dict1_key, dict1_values in dict1.iteritems():
    for dict1_value in dict1_values:
        try:
            dict2_value = dict2[dict1_value]
            print str(dict1_key) + '\t' + str(dict1_value) + '\t' + str(dict2_value)
        except KeyError:
            pass

这结合了一些技术来加速它并使用更少的内存。 iteritems 使用更少的内存(正如其他人提到的那样)。通过使用try,然后使用dict2[dict1_value],您可以确保dict2 只被搜索一次,然后使用哈希算法,这应该比遍历所有元素要快得多。对于dict2 中没有dict1_value 的所有情况,try 下的第一条语句失败,导致catch 块无害地pass

【讨论】:

  • 您的意思是“除外”而不是“捕获”吗?这似乎很容易,但它从不打印任何东西。这真的是条件语句:“dict2_value = dict2[dict1_value]”吗?即使我删除 try 和 catch 之间的所有内容,只打印 dict2_value,也不会打印任何内容
  • @Vince 是的,应该是except。 try 下的第一行是一个赋值,而不是条件语句。如果dict2 缺少dict1_value 键,分配将导致错误,这会导致try 块结束并接管except 块。随着更改为except,然后在问题中输入dict1dict2,我得到三行输出(每个人在字典之间共享一行),包括girls\tsuzy\tpaper-stapler-extraordinaire
  • 嗯。所以我的字典与上面的格式完全相同,除了不同的项目。此代码不适用于他们。但是当我像上面那样专门使用 dict1 和 dict2 时,这是可行的。它们是如何创建的重要吗?具体来说,如果我以下面的方式创建我的 dict,然后使用上面的代码,以这种方式指定值,它就不起作用。有什么区别?如果 uid 不在 dict2 中:\n dict2[uid] = []\n dict2[uid].append(object)
  • 该代码旨在让 dict2 包含标量字符串值。我通过将dict2_value 替换为str(dict2_value) 对其进行了修改以使用数组。以前,Python 会尝试将 dict2_value 添加到字符串中但失败了。我已经修改了代码以在运行时显示这样的错误,方法是指定 KeyError 来捕获要捕获的错误类型。
【解决方案2】:

您是否正在寻找以下方面的内容:

[(k,i,dict2[i]) for k,v in dict1.items() for i in v if i in set(dict2.keys())]

它返回 dict1 的键、dict1 的值和 dict1 中作为 dict2 中的键的每个值的 dic2 值。可以对其进行编辑以返回字符串等...

这个输出:

[('boys', 'tom', 'garbage-specialist'),
 ('boys', 'jon', 'paper-shredderoligist'),
 ('girls', 'suzy', 'paper-stapler-extraordinaire')]

dict2.keys() 上的 set() 用于加快键查找速度。

【讨论】:

  • 我不断收到 TypeError: unhashable type: 'list' 使用此错误
  • 我不知道如何解决这个问题。我认为这是值列表的问题,这就是我最初问这个问题的原因。据我了解,该语句的流程如下:1)对于dict2 [v]中的k,v,对于dict1.items中的k,v,如果值在dict2中,则打印任何内容。如果我删除设置部分,错误就消失了,但它会打印一个空列表。套装有什么作用?谢谢。
  • 该集合允许更快地查找以查看值是否在键中。不幸的是,我最初查找的值是一个列表,并且列表是不可散列的(相反,您需要使用元组)。我已更改答案以查找列表中的每个单独值。
  • 啊,完美。谢谢。很高兴知道有关集合的信息
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-02
  • 1970-01-01
  • 1970-01-01
  • 2017-06-21
相关资源
最近更新 更多