32

我试图在两个不同的字典中找到相应的键。每个都有大约 600k 条目。

比如说:

    myRDP = { 'Actinobacter': 'GATCGA...TCA', 'subtilus sp.': 'ATCGATT...ACT' }
    myNames = { 'Actinobacter': '8924342' }

我想打印出 Actinobacter (8924342) 的值,因为它与 myRDP 中的值匹配。

以下代码有效,但速度很慢:

    for key in myRDP:
        for jey in myNames:
            if key == jey:
                print key, myNames[key]

我尝试了以下方法,但它总是导致 KeyError:

    for key in myRDP:
        print myNames[key]

是否有可能在 C 中实现了一个函数来执行此操作?我用谷歌搜索,但似乎没有任何效果。

谢谢。

4

11 回答 11

50

intersection使用集合,因为它们有一个应该很快的内置方法:

myRDP = { 'Actinobacter': 'GATCGA...TCA', 'subtilus sp.': 'ATCGATT...ACT' }
myNames = { 'Actinobacter': '8924342' }

rdpSet = set(myRDP)
namesSet = set(myNames)

for name in rdpSet.intersection(namesSet):
    print name, myNames[name]

# Prints: Actinobacter 8924342
于 2009-08-23T00:32:07.080 回答
48

你可以这样做:

for key in myRDP:
    if key in myNames:
        print key, myNames[key]

您的第一次尝试很慢,因为您将myRDP 中的每个键与 myNames 中的每个进行比较。用算法术语来说,如果 myRDP 有n 个元素,而 myNames 有m个元素,那么该算法将需要 O( n × m ) 次操作。对于每个 600k 元素,这是 360,000,000,000 次比较!

但是测试一个特定元素是否是字典的键是很快的——事实上,这是字典的定义特征之一。在算法术语中,key in dict测试是 O(1),或恒定时间。所以我的算法将花费 O( n ) 时间,这是 600,000 分之一的时间。

于 2009-08-23T00:30:01.247 回答
24

在 python 3 你可以做

myNames.keys() & myRDP.keys()

于 2017-01-27T15:18:53.613 回答
9
for key in myRDP:
    name = myNames.get(key, None)
    if name:
        print key, name

dict.getNone如果键不存在,则返回您给它的默认值(在本例中为)。

于 2009-08-23T00:30:47.813 回答
7

您可以从查找公共键开始,然后对其进行迭代。集合操作应该很快,因为它们是用 C 实现的,至少在现代版本的 Python 中是这样。

common_keys = set(myRDP).intersection(myNames)
for key in common_keys:
    print key, myNames[key]
于 2009-08-23T00:34:51.217 回答
2

请改用以下get方法:

 for key in myRDP:
    value = myNames.get(key)
    if value != None:
      print key, "=", value
于 2009-08-23T00:31:06.597 回答
2

最好和最简单的方法是简单地执行常见的集合操作(​​Python 3)。

a = {"a": 1, "b":2, "c":3, "d":4}
b = {"t1": 1, "b":2, "e":5, "c":3}
res = a.items() & b.items() # {('b', 2), ('c', 3)} For common Key and Value
res = {i[0]:i[1] for i in res}  # In dict format
common_keys = a.keys() & b.keys()  # {'b', 'c'}

干杯!

于 2019-05-31T16:25:48.503 回答
1

您可以简单地编写此代码,它会将公共密钥保存在列表中。 common = [i for i in myRDP.keys() if i in myNames.keys()]

于 2020-05-30T11:03:16.447 回答
0

将两个字典复制到一个字典/数组中。这是有道理的,因为您有 1:1 的相关值。那么你只需要一次搜索,不需要比较循环,并且可以直接访问相关值。

示例结果字典/数组:

[Name][Value1][Value2]

[Actinobacter][GATCGA...TCA][8924342]

[XYZbacter][BCABCA...ABC][43594344]

...

于 2009-08-23T00:31:43.493 回答
0

这是我对字典进行交集、并集、差异和其他集合操作的代码:

class DictDiffer(object):
    """
    Calculate the difference between two dictionaries as:
    (1) items added
    (2) items removed
    (3) keys same in both but changed values
    (4) keys same in both and unchanged values
    """
    def __init__(self, current_dict, past_dict):
        self.current_dict, self.past_dict = current_dict, past_dict
        self.set_current, self.set_past = set(current_dict.keys()), set(past_dict.keys())
        self.intersect = self.set_current.intersection(self.set_past)
    def added(self):
        return self.set_current - self.intersect 
    def removed(self):
        return self.set_past - self.intersect 
    def changed(self):
        return set(o for o in self.intersect if self.past_dict[o] != self.current_dict[o])
    def unchanged(self):
        return set(o for o in self.intersect if self.past_dict[o] == self.current_dict[o])

if __name__ == '__main__':
    import unittest
    class TestDictDifferNoChanged(unittest.TestCase):
        def setUp(self):
            self.past = dict((k, 2*k) for k in range(5))
            self.current = dict((k, 2*k) for k in range(3,8))
            self.d = DictDiffer(self.current, self.past)
        def testAdded(self):
            self.assertEqual(self.d.added(), set((5,6,7)))
        def testRemoved(self):      
            self.assertEqual(self.d.removed(), set((0,1,2)))
        def testChanged(self):
            self.assertEqual(self.d.changed(), set())
        def testUnchanged(self):
            self.assertEqual(self.d.unchanged(), set((3,4)))
    class TestDictDifferNoCUnchanged(unittest.TestCase):
        def setUp(self):
            self.past = dict((k, 2*k) for k in range(5))
            self.current = dict((k, 2*k+1) for k in range(3,8))
            self.d = DictDiffer(self.current, self.past)
        def testAdded(self):
            self.assertEqual(self.d.added(), set((5,6,7)))
        def testRemoved(self):      
            self.assertEqual(self.d.removed(), set((0,1,2)))
        def testChanged(self):
            self.assertEqual(self.d.changed(), set((3,4)))
        def testUnchanged(self):
            self.assertEqual(self.d.unchanged(), set())
    unittest.main()
于 2009-08-23T02:24:02.163 回答
0
def combine_two_json(json_request, json_request2):
intersect = {}

for item in json_request.keys():
    if item in json_request2.keys():
        intersect[item]=json_request2.get(item)
return intersect
于 2020-05-30T10:51:57.883 回答