我有一本这样的字典
{
"key1": ["1", "3", "4", "7"],
"key2": ["7", "3", "2", "1"],
"key3": ["5", "2", "3", "1"],
"key4": ["4", "5", "1", "3"]
}
这是一本样本词典,真正的要大得多。 我需要按列表中的重复项对键进行分组,以便输出结果如下所示:
key1
和key2
在它们各自的列表中都有"1"
、"7"
和"3"
,因此它们必须分组在group3.1
中-这意味着这些键在它们的列表中有3个公共项,这是此类的第一组(其中有3个公共项)。你知道吗
key2
和key3
在它们的列表中都有“3”、“2”和“1”项,因此这些键属于group3.2—这意味着这些键在列表中有3个公共项,这是此类键的第二组
等等。。。你知道吗
只有当键的列表中有2个或更多公共项时,才可以对它们进行分组。这些组的顺序并不重要,因此group3.1可以被划分为group3.2,group3.2可以被称为group3.1,等等。唯一重要的是组名中的第一个数字,它表示给定键共有多少项。你知道吗
所有这一切的重点是我需要知道什么键有多少其他键在他们的列表中相似的项目方面的共同点。了解钥匙之间的距离。你知道吗
我想要的输出结果是一个类似这样的字典
{
"group3.1": ["key1", "key2"],
"group3.2": ["key2", "key3"],
"group2.1": ["key1", "key3", "key4"]
}
非常感谢您的帮助!你知道吗
可能的预处理
先删除唯一的URL
由于您有许多键,但按键只有10个URL,因此一种可能的优化方法是:
根据URL的分布情况,它可能不会更改任何内容,也可能会删除大部分密钥。你知道吗
不管怎么说,这种预处理比暴力的二次解决方案要快得多,所以它可能是值得的。你知道吗
在上面的例子中,由于预处理,从原始dict中删除了
key5
和key6
。你知道吗查找可能的成对键
对于每个键,可以重用
keys_by_url
来查找至少有两个共同URL的键:它输出:
这应该是非常快的,只会留下有趣的密钥对。然后你就可以用这两对了@胡安帕.阿里维拉加的solution而不是
itertools.combinations
。你知道吗较短版本
它输出:
所以,我想不出一个聪明的解决方案,不需要将每个值集与其他值集进行比较。我不指望这是非常性能,但它可能足够了。首先,让我们从我们的字典开始:
现在,我们将把列表改为
frozensets
这允许我们获得交叉点,并且可以散列:
所以,现在我们创建一个中间层。这将花费最长的处理时间:
现在我们有了你想要的数据,但是现在有了你想要的密钥方案。为此,我们可以采取如下措施:
最后:
不幸的是,创建
inverse
的步骤将是多项式时间。它至少是O(n^2),其中n是字典的大小,但实际上,我认为它是O(n^2*m),其中m是键之间成对最小长度的最大值。可能不太可怕。编辑刚刚注意到在一条评论中,每个值都是10个URL的列表。在这种情况下,第二个中间步骤仅仅是O(n^2),因为m是常数。你知道吗相关问题 更多 >
编程相关推荐