Python字典更新异常求助:排序算法数据采集场景
问题排查与解决思路
核心问题分析
你遇到的数据覆盖问题,大概率是两个原因叠加导致:
- 全局统计变量的递归污染:归并、快排都是递归算法,全局变量会被所有递归分支共享。哪怕外层循环初始化了变量,递归过程中所有调用都会修改同一个全局值,不同排序任务的统计数据会互相干扰。
- 字典键冲突或引用复用:如果你的字典键设计重复(比如只按算法+数据大小作为键),后续循环的同组合数据会直接覆盖之前的;或者你复用了同一个统计对象(比如列表)存数据,导致新数据覆盖旧数据。
具体修复方案
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
相关产品推荐
相关产品推荐

