【问题标题】:Why does my Python code thinks a variable is a str when it should be an int?为什么我的 Python 代码认为一个变量应该是一个 int 却是一个 str?
【发布时间】:2021-04-17 04:44:27
【问题描述】:

因此,我们在课堂上制作了一个 Python 程序,用于提取有关交通事故的数据。 我们从中提取的文件是一个表格,每行提供有关给定事故所涉及人员的信息

usagers_2016 = open('usagers_2016.csv','w',encoding='utf8', errors='ignore', newline="\n")
usagers_2016.write("Num_Acc;place;catu;grav;sexe;trajet;secu;locp;actp;etatp;an_nais;num_veh\n
201600000001;1;1;1;2;0;11;0;0;0;1983;B02\n
201600000001;1;1;3;1;9;21;0;0;0;2001;A01\n
201600000002;1;1;3;1;5;11;0;0;0;1960;A01\n
201600000002;2;2;3;1;0;11;0;0;0;2000;A01\n
201600000002;3;2;3;2;0;11;0;0;0;1962;A01\n
201600000003;1;1;1;1;1;11;0;0;0;1997;A01\n")

next(usagers_2016)

dict_acc = {}

for ligne in usagers_2016.readlines():
    ligne = ligne[:-2].split(";")

我选择在字典中提取信息,其中事故是关键,每个关键的值是一个列表,其第一个元素是相关人员的列表,每个人都由一个列表表示,包括他们的性别和出生年份

    if ligne[0] not in dict_acc.keys():
        dict_acc[ligne[0]] = [[],0,0,0,0]
    dict_acc[ligne[0]][0].append([ligne[4],ligne[10]])

usagers_2016.close()

for accident in dict_acc:
    accident[1] = len(accident[0]) # TypeError: 'str' object does not support item assignment

我的问题如下:我想添加,作为主列表的第二个元素(key的值),每次事故涉及的人数(也就是第一个元素的len()(列表)的列表)。然而,在代码运行过程中发现,第一个 0(前面代码摘录的第 2 行)被认为是str,并且无法接收任何项目分配。问题是它应该是int!!!!我认为将int 类型显式为dict_acc[ligne[0]] = [[],int(0),int(0),int(0),int(0)] 之后会更正它,但是不,我的0 仍然被视为字符串。你知道为什么吗?

【问题讨论】:

  • 您可以发布usagers_2016.csv 的示例,以便其他人可以运行代码,不过最好还是使用csv.reader 阅读本文
  • 您能否解释一下您在代码中的哪一行遇到了错误
  • @NirElbaz 错误在最后一行:TypeError: 'str' object does not support item assignment
  • split() 返回一个字符串列表。即使字符串完全由数字组成也是如此。让您的代码在您期望为数字的列值上调用 int()。并为数据不符合您预期的情况做好准备。
  • 目前还不清楚您在该行中尝试做什么,或者您为什么希望它起作用。你能澄清一下吗?请注意,for accident in dict_acc: 将遍历字典的 keys,正如您自己所说的“事故是关键所在”。对于第一个条目,键 accident"201600000001",所以 accident[1]"0" 并且您的代码会尝试设置它。 即使键是数字,这也没有意义。 虽然字符串不支持项目分配,但数字根本没有项目的概念。

标签: python string integer typeerror


【解决方案1】:

原因是您在打开文件时读取文件,您有一个_io.TextIOWrapper 类型的对象,并且每一行都是一个字符串,稍后您将根据分隔符';' 对其进行拆分。

next(usagers_2016) 行让我觉得您正在删除带有标题的第一行。

所以你可以做的是在 Pandas 中将这个 csv 作为 Dataframe 打开,如下所示:

import pandas as pd
df = pd.read_csv ('usagers_2016.csv', sep=';')
# To remove the tailing \n
df.columns=df.columns.str.replace(r'\n','')
df.replace(r'\\n','', regex=True)

# Now to calculate the number of people involve in each accident you can
df.groupby(['Num_Acc']).size()

【讨论】:

  • 这无法解决他们的操作accident[1] = len(accident[0]) 没有意义,无论是对字符串还是整数执行。
  • @MisterMiyagi 你是对的,没有修复。通过我的回答,用户至少可以获得不同列中的字​​段。我相信现在她正在尝试按键分组,即她档案Num_Acc 中的第一列,以及计算事故中有多少人受伤,我相信这是列catu。问题是她试图遵循的方法会非常复杂,当使用数据框时,她的操作可能看起来更直观,甚至更容易询问
  • 我怀疑df.columns.str.replace(r'\\n','')之类的操作是否特别直观,除非熟悉pandas。 (我仍然不明白为什么要删除 r'\\n' 而不是 '\n'。)无论哪种方式,无论直观与否,它都无法以任何方式解决问题。
  • @MisterMiyagi 在她共享的文件中,每行末尾都有一个额外的\n,即使对于标题也是如此。如果她确认她想要达到的计数是多少,我将编辑我的 anwser
  • 问题中显示的数据包含\n,也就是一个换行符。 r'\\n' 是三个字符,即\\n,因为r 禁用转义,而\\ 将是转义的\
【解决方案2】:

好的,问题是我打电话给accident[1]而不是dict_acc[accident][1]

解决办法

for accident in dict_acc:
    dict_acc[accident][1] = len(dict_acc[accident][0])

感谢@MisterMiyagi

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多