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

如何编写read_data函数读取chocolates.txt为值是元组列表的字典?

问题与解决方案

问题背景

我有一个名为chocolates.txt的文件,内容如下:

Mary;dark;0.5
Steve;dark;0.5
Mary;toffee;2
Mary;white;0.25
Steve;raspberry;1
Mary;milk;1.25

需要编写read_data函数,返回格式如下的字典:

>>> read_data('chocolates.txt')
{'Mary': [('dark', 0.5), ('toffee', 2.0), ('white', 0.25), ('milk', 1.25)], 'Steve': [('dark', 0.5), ('raspberry', 1.0)]}

字典的值是由元组组成的列表。我尝试了以下代码(想先把数据存入集合再转为元组)但无法运行:

def read_data(file):
d = {}
f = open(file, encoding='utf-8')
for row in file:
    x = row.strip().split(";")
    buyer = x[0]
    if not buyer in d:
        d[buyer] = set()
        kd[buyer].add(x[1:])
    f.close()
    return d

请问有没有其他实现方法?

你的代码问题分析

先说说这段代码的几个明显问题:

  • 缩进错误:Python靠缩进区分代码块,函数内的所有代码都需要缩进
  • 遍历对象错误:for row in file应该是for row in f,file是文件名字符串,不是可遍历的文件对象
  • 变量名错误:kd[buyer]是笔误,应该是d[buyer]
  • 逻辑错误:只有当买家不在字典里时才添加数据,后续同一买家的条目会被忽略;而且集合是无序的,无法保证和文件中的顺序一致
  • 代码位置错误:f.close()和return d放在了循环内部,第一次循环就会关闭文件并返回,根本处理不了所有行
  • 数据类型问题:x[1:]是字符串列表,需要把重量转为浮点数,再转成元组

可行的实现方法

方法一:基础字典操作

用最基础的字典逻辑实现,手动处理键的初始化:

def read_data(file_path):
    result = {}
    # 使用with语句自动管理文件,无需手动关闭
    with open(file_path, encoding='utf-8') as f:
        for line in f:
            # 处理每行数据,去除首尾空白后按分号分割
            parts = line.strip().split(';')
            # 跳过格式不正确的行(比如空行、分割后不足3个元素的行)
            if len(parts) != 3:
                continue
            buyer, chocolate, weight = parts
            # 将重量字符串转为浮点数
            weight_float = float(weight)
            # 如果买家不在字典中,初始化空列表
            if buyer not in result:
                result[buyer] = []
            # 将元组添加到对应列表
            result[buyer].append((chocolate, weight_float))
    return result

方法二:用collections.defaultdict简化代码

借助defaultdict可以自动为不存在的键创建空列表,省去判断键是否存在的步骤:

from collections import defaultdict

def read_data(file_path):
    # defaultdict会自动为新键生成空列表
    result = defaultdict(list)
    with open(file_path, encoding='utf-8') as f:
        for line in f:
            parts = line.strip().split(';')
            if len(parts) != 3:
                continue
            buyer, chocolate, weight = parts
            result[buyer].append((chocolate, float(weight)))
    # 转成普通字典返回(如果不需要defaultdict的特性,转成普通字典更符合需求)
    return dict(result)

为什么不用集合?

你原本想使用集合,但集合有两个问题不适合这个场景:

  1. 无序性:集合无法保证元素的顺序和文件中的一致,而题目要求的列表是按文件顺序排列的
  2. 去重特性:如果文件中有重复的条目(比如同一买家买了同一种巧克力多次),集合会自动去重,但需求是保留所有记录

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 01:31:16