【问题标题】:Counting "unique pairs" of numbers into a python dictionary?将“唯一对”的数字计数到python字典中?
【发布时间】:2018-09-06 02:59:21
【问题描述】:

编辑:编辑错别字;字典的键值应该是字典,而不是集合。

不过,我会在此处保留拼写错误,因为下面的问题解决了这个问题。对于造成的混乱,我深表歉意。

问题来了:

假设我有一个从不重复的整数列表:

list1 = [2, 3]   

在这种情况下,有一个唯一的对 2-3 和 3-2,所以字典应该是:

{2:{3: 1}, 3:{2: 1}}

即有1对2-3和1对3-2。

对于较大的列表,配对是相同的,例如

list2 = [2, 3, 4]

有字典

{2:{3: 1}, 3:{2: 1}, 3:{4: 1}, 4:{3: 1}, 2:{4: 1}, 4:{2: 1}}

(1) 一旦列表的大小变得更大,如何使用python数据结构在算法上找到这种格式的“唯一对”?

(2) 我提到列表不能有重复的整数,例如

[2, 2, 3]

是不可能的,因为有两个 2。

但是,可能有一个列表列表:

list3 = [[2, 3], [2, 3, 4]] 

字典必须是

{2:{3: 2}, 3:{2: 2}, 3:{4: 1}, 4:{3: 1}, 2:{4: 1}, 4:{2: 1}}

因为有两对 2-3 和 3-2。给定列表中的多个列表,如何“更新”字典?

这是一个算法问题,我不知道最有效的解决方案。我的想法是以某种方式缓存列表中的值并枚举对......但这会很慢。我猜itertools 有一些有用的东西。

【问题讨论】:

  • 我认为您的预期输出错误,与您描述的不符。
  • 同意@OlivierMelançon;请澄清输入和预期输出。 (您的输出还使用集合,它们是无序集合,{3, 1}{1, 3} 是等价的)
  • 另外,它没有多大意义......你说一个数字不能重复,那么每个可能的对的答案都是两个。
  • @OlivierMelançon 对不起。请看编辑。这些应该是字典值,而不是集合。
  • @ReblochonMasque 对不起。请看编辑。这些应该是字典值,而不是集合。

标签: python python-3.x dictionary itertools nested-lists


【解决方案1】:

您想要计算列表中的组合产生的对。您可以找到带有Countercombinations 的人。

from itertools import combinations
from collections import Counter

list2 = [2, 3, 4]

count = Counter(combinations(list2, 2))

print(count)

输出

Counter({(2, 3): 1, (2, 4): 1, (3, 4): 1})

对于您的列表列表,我们使用每个子列表的结果更新Counter

from itertools import combinations
from collections import Counter

list3 = [[2, 3], [2, 3, 4]]

count = Counter()

for sublist in list3:
    count.update(Counter(combinations(sublist, 2)))

print(count)

输出

Counter({(2, 3): 2, (2, 4): 1, (3, 4): 1})

【讨论】:

  • 库函数的出色使用。它几乎总是比一次性的临时代码更可取,因为这里的编辑器不容易调试。
【解决方案2】:

我的方法迭代输入 dict(线性复杂度)并将每个键与其第一个可用整数配对(这种复杂度取决于您问题的确切规格 - 例如,每个列表是否可以包含无限的子列表?),将这些插入输出字典(恒定复杂度)。

import os 
import sys 


def update_results(result_map, tup):
    # Update dict inplace
    # Don't need to keep count here
    try:
        result_map[tup] += 1
    except KeyError:
        result_map[tup] = 1
    return


def algo(input):
    # Use dict to keep count of unique pairs while iterating
    # over each (key, v[i]) pair where v[i] is an integer in 
    # list input[key]
    result_map = dict()
    for key, val in input.items():
        key_pairs = list()
        if isinstance(val, list):
            for x in val:
                if isinstance(x, list):
                    for y in x:
                        update_results(result_map, (key, y))
                else:
                    update_results(result_map, (key, x))
        else:
            update_results(result_map, (key, val))
    return len(result_map.keys())


>>> input = { 1: [1, 2], 2: [1, 2, [2, 3]] }
>>> algo(input)
>>> 5

我很确定有一种更完善的方法可以做到这一点(同样,这取决于您问题的确切规格),但这可以帮助您入门(无导入)

【讨论】:

    猜你喜欢
    • 2015-09-29
    • 1970-01-01
    • 2023-04-06
    • 2019-01-30
    • 2016-02-04
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多