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

Python字典更新异常求助:排序算法数据采集场景

问题排查与解决思路

核心问题分析

你遇到的数据覆盖问题,大概率是两个原因叠加导致:

  1. 全局统计变量的递归污染:归并、快排都是递归算法,全局变量会被所有递归分支共享。哪怕外层循环初始化了变量,递归过程中所有调用都会修改同一个全局值,不同排序任务的统计数据会互相干扰。
  2. 字典键冲突或引用复用:如果你的字典键设计重复(比如只按算法+数据大小作为键),后续循环的同组合数据会直接覆盖之前的;或者你复用了同一个统计对象(比如列表)存数据,导致新数据覆盖旧数据。

具体修复方案

1. 抛弃全局变量,用类封装独立统计

把比较、交换次数封装到类实例里,每个排序任务用单独的实例,彻底隔离统计数据:

class SortStats:
    def __init__(self):
        self.comparisons = 0
        self.swaps = 0

    def add_compare(self):
        self.comparisons += 1

    def add_swap(self):
        self.swaps += 1

2. 修改递归排序算法,传入统计实例

以归并排序为例,把统计对象作为参数传入递归函数,所有比较/交换操作都调用实例方法:

def merge_sort(arr, stats):
    if len(arr) > 1:
        mid = len(arr) // 2
        left = arr[:mid]
        right = arr[mid:]

        merge_sort(left, stats)
        merge_sort(right, stats)

        i = j = k = 0
        while i < len(left) and j < len(right):
            stats.add_compare()
            if left[i] < right[j]:
                arr[k] = left[i]
                i += 1
            else:
                arr[k] = right[j]
                j += 1
            k += 1

        # 剩余元素拷贝(无比较/交换,无需统计)
        while i < len(left):
            arr[k] = left[i]
            i += 1
            k += 1

        while j < len(right):
            arr[k] = right[j]
            j += 1
            k += 1

快排的修改逻辑完全一致:所有比较操作调用stats.add_compare(),交换操作调用stats.add_swap(),并把stats传入递归的分区函数。

3. 重构循环与字典存储逻辑

用列表存储每个试验的独立字典条目(避免键冲突覆盖),并且每次排序都传入数组副本、创建新的统计实例:

import time
import pandas as pd
import random

# 初始化结果列表(替代单个字典)
sort_results = []

# 四层循环示例(按你的实际循环调整)
for algo_name in ["merge_sort", "quick_sort"]:
    for data_size in [100, 500, 1000, 2000]:
        for data_pattern in ["random", "sorted", "reverse"]:
            for trial_num in range(3):  # 重复3次取平均
                # 生成目标数据集
                if data_pattern == "random":
                    raw_data = random.sample(range(100000), data_size)
                elif data_pattern == "sorted":
                    raw_data = list(range(data_size))
                else:
                    raw_data = list(range(data_size, 0, -1))
                
                # 初始化当前试验的统计实例
                current_stats = SortStats()
                # 排序计时(传入数组副本,避免修改原数据)
                start_time = time.time()
                if algo_name == "merge_sort":
                    merge_sort(raw_data.copy(), current_stats)
                else:
                    quick_sort(raw_data.copy(), current_stats)
                elapsed_time = time.time() - start_time
                
                # 存入当前试验的完整数据
                sort_results.append({
                    "algorithm": algo_name,
                    "data_size": data_size,
                    "data_pattern": data_pattern,
                    "trial": trial_num,
                    "time_cost": elapsed_time,
                    "comparison_count": current_stats.comparisons,
                    "swap_count": current_stats.swaps
                })

# 转DataFrame并导出CSV
df = pd.DataFrame(sort_results)
df.to_csv("sort_algorithm_stats.csv", index=False)

额外排查点

  • 检查你之前的字典更新逻辑:如果是用result_dict[unique_key] = stats,确认unique_key是否包含所有维度(算法、数据大小、数据类型、试验次数),缺任何一个都会导致覆盖。
  • 确保排序时操作的是数组副本:如果直接修改原数据集,后续试验的输入数据会变成已排序状态,导致统计结果完全失真。

内容的提问来源于stack exchange,提问作者How why e

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 08:33:19