You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化字典列表值迭代统计:计算历史频次覆盖当前元素的方案

问题需求

现有一个以升序日期字符串为键、整数列表为值的字典,需完成以下计算:

  • 对每个键值对,遍历两组参数:过去记录次数P(取值7、8、9),出现次数阈值M(取值2、3)
  • 统计过去P次记录中出现次数≥M的数字,与当前键对应列表数字的交集数量
  • 示例:键L19981120对应的列表[2,3,5]中,有2个数字在过去9次记录中出现了至少3次

当前实现存在代码冗余、仅输出部分迭代结果的问题,需要更优的正确实现方式。


现有实现代码

data = {
"L19980909":    [11,12,25],
"L19981013":    [19,28,31],
"L19981016":    [4,9,31],
"L19981020":    [8,11,17],
"L19981023":    [5,22,25],
"L19981027":    [5,20,27],
"L19981030":    [12,19,26],
"L19981105":    [31,32,38],
"L19981109":    [2,22,24],
"L19981110":    [2,16,19],
"L19981113":    [9,15,17],
"L19981119":    [2,10,11],
"L19981120":    [2,3,5],
"L19981126":    [4,6,14],
"L19981127":    [5,9,18],
"L19981201":    [1,6,7]}

value_list = list(data.values())

for idx, (k, v) in enumerate(data.items()):
    ever_more_than_times = []
    for how_many_past in [7,8,9]:
        if idx >= how_many_past:
            past_appeared = sum(value_list[idx-how_many_past:idx],[])
        
            for more_than_times in [2,3]:
                if how_many_past > more_than_times:
                
                    for ox in list(range(1,40)):
                        if past_appeared.count(ox) >= more_than_times:
                            ever_more_than_times.append(ox)
    ever_more_than_times = list(set(ever_more_than_times))

    hit = len(set(ever_more_than_times) & set(v))

    if hit != 0:
        print (k,'$',v,'$',how_many_past,'$',more_than_times,'$',hit)

现有输出

L19981105 $ [31, 32, 38] $ 9 $ 3 $ 1
L19981110 $ [2, 16, 19] $ 9 $ 3 $ 1
L19981119 $ [2, 10, 11] $ 9 $ 3 $ 1
L19981120 $ [2, 3, 5] $ 9 $ 3 $ 2
L19981127 $ [5, 9, 18] $ 9 $ 3 $ 1

优化后的实现代码

from collections import defaultdict

data = {
    "L19980909": [11,12,25],
    "L19981013": [19,28,31],
    "L19981016": [4,9,31],
    "L19981020": [8,11,17],
    "L19981023": [5,22,25],
    "L19981027": [5,20,27],
    "L19981030": [12,19,26],
    "L19981105": [31,32,38],
    "L19981109": [2,22,24],
    "L19981110": [2,16,19],
    "L19981113": [9,15,17],
    "L19981119": [2,10,11],
    "L19981120": [2,3,5],
    "L19981126": [4,6,14],
    "L19981127": [5,9,18],
    "L19981201": [1,6,7]
}

# 提取按日期升序排列的记录列表(Python3.7+字典保留插入顺序)
record_list = list(data.items())

for idx, (current_key, current_nums) in enumerate(record_list):
    current_num_set = set(current_nums)
    # 遍历所有P和M的参数组合
    for P in [7, 8, 9]:
        if idx < P:
            continue  # 历史记录不足P条,跳过
        # 收集过去P次记录的所有数字
        past_nums = []
        for _, nums in record_list[idx-P:idx]:
            past_nums.extend(nums)
        # 统计数字出现次数
        count_dict = defaultdict(int)
        for num in past_nums:
            count_dict[num] += 1
        # 遍历M阈值
        for M in [2, 3]:
            # 筛选出符合次数要求的数字集合
            qualified_nums = {num for num, cnt in count_dict.items() if cnt >= M}
            # 计算交集数量
            hit_count = len(current_num_set & qualified_nums)
            # 输出结果,可根据需求修改输出格式或过滤条件
            print(f"{current_key} $ {current_nums} $ {P} $ {M} $ {hit_count}")

优化点说明

  1. 修复输出不完整问题:原代码仅保留最后一组P、M参数的结果,优化后遍历所有P和M的组合,输出每个键值对对应所有参数的计算结果
  2. 提升性能:
    • 用defaultdict统计数字出现次数,替代原代码中反复调用list.count()的低效操作(原代码每次count都会遍历整个列表,时间复杂度O(n),优化后仅遍历一次)
    • 提前将当前列表转为集合,减少交集计算的时间开销
  3. 简化逻辑:减少嵌套层级,变量命名更直观,代码结构清晰易读
  4. 兼容性:依赖Python3.7+的字典插入顺序特性,符合原数据升序日期的要求

内容的提问来源于stack exchange,提问作者Mark K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 08:45:38