【问题标题】:Python Write to Tuple Error with appendPython写入元组错误与追加
【发布时间】:2015-04-22 18:43:29
【问题描述】:


我正在练习 Python 3.3.2,我想练习对元组的追加技术。
我有一个名为 user_scores.txt. 的文本文件,其中包含我工作场所的人为数学问题提交的分数。他们提交了他们可以产生的不同答案。文件如下图(Alex只提交了两个):

Alex, 35, 39
Daniel, 34, 35, 36 
Richard, 21, 23, 24

我正在尝试以这种形式将这些分数写入元组:

Name:Score, Score, Score.

例如:
Alex:35, 39,
Daniel:34, 35, 36

我已经尝试使用下面的代码,但它不起作用,因为它返回下面的错误:

user_scores = []

with open('user_scores.txt') as f:
    for line in f:
        worker,score = line.strip().replace("\n","").split(",")
        user_scores[worker].append(int(score))

错误:

ValueError: too many values to unpack (expected 2)

解决方法是什么?我的代码块是完全错误的还是什么?

谢谢,朵拉。

【问题讨论】:

  • @ITellMyselfSecrets 我没有完全考虑到它。使用字典而不是元组有什么好处?
  • 您可以通过将名称作为键更轻松地访问分数

标签: python append tuples python-idle


【解决方案1】:

看起来您正在尝试写入列表,而不是元组。元组是不可变的,所以无论如何这是不可能的。看起来您还试图通过字符串索引列表。这是不可能的,因为列表需要按数字索引。我认为你想要的是一个字典。

还有,当你这样做时

worker, score = [list of things]

python 期望事物列表中包含 2 个项目。显然,您将拥有可变数量的东西。

试试这个:

user_scores = {}

with open('user_scores.txt') as f:
    for line in f:
        this_line = line.strip().replace("\n","").split(",")
        user_scores[this_line[0]] = this_line[1:]

这将创建一个您可以通过一个人的名字访问的字典,并返回一个他们的分数列表,无论列表中有多少东西。对于每一行,它将用逗号分隔该行中的所有内容,将键设为人名,并将值设为他们的分数列表。

如果您希望将分数存储为数字而不是字符串,请将最后一行替换为:

user_scores[this_line[0]] = [int(score) for score in this_line[1:]]

在这种情况下使用列表比使用元组存储分数更好,因为可以附加到可变类型的列表,但不能附加到不可变类型的元组。

【讨论】:

  • 虽然 OP 在他的代码中包含了它,for line in f 意味着不可能有任何换行符可以替换。
【解决方案2】:

首先让我们修复您的数据结构。您通过考生姓名引用每个分数元组。通过键(而不是索引)引用值是使用字典完成的。

user_scores = dict() # or = {}. Same difference.

那么我们知道两件事:

  1. 每行的第一项将是应试者的姓名
  2. 之后会有一些分数,都是整数

所以我们可以像这样遍历文件:

with open('path/to/file.txt') as infile:
    for line in infile:
        name, *scores = line.strip().split(',')

那里的 glob * 告诉 Python 会有很多这样的,所以创建一个大小相等的元组。 a, *b = (1, 2, 3, 4, 5) 使 a = 1; b = (2, 3, 4, 5)。现在,分配您的值很容易!

user_scores[name] = [int(score) for score in scores]

请注意,这会创建一个列表,而不是一个元组,但这很可能是您想要的。元组表明每个元素的位置不仅重要,而且有意义。这很容易解释为二维坐标平面中的一个点,表示为有序对

#x, y
(1, 10)

有很大不同
#x , y
(10, 1)

在列表中,列表保持其顺序可能很重要,但所有元素的含义相同。这就是你的用例——它们都是分数,你可能想要关联每个应试者随着时间的推移而提高,但最终如果测试分数移动到不同的位置,它不会改变它的事实还是考试成绩。

【讨论】:

  • 此解决方案抛出无效语法错误name, *scores = line.strip().split(',')
  • @ITellMyselfSecrets - 仅在 Python 2.x 中,*scores 语法不存在。但 OP 使用的是 Python 3。
  • @ITellMyselfSecrets 使用 Python3 的另一个理由!它也很聪明。如果我只需要每个部分的一些东西,我可以做header, row1, row2, *_, last_row = line.split(',') 或等等。
  • 我发现你的回答非常聪明和干净,想自己尝试一下。
猜你喜欢
  • 1970-01-01
  • 2015-09-08
  • 2011-12-08
  • 1970-01-01
  • 1970-01-01
  • 2015-02-16
  • 2022-09-28
相关资源
最近更新 更多