Python—如何更新在文件中的行上迭代的for循环的索引?

Python—如何更新在文件中的行上迭代的for循环的索引?,python,indexing,variable-assignment,Python,Indexing,Variable Assignment,使用for循环,我迭代文件中的行。鉴于这一点: line= [ ‘641', '"Tornadus', ' (Incarnate Form)"', '"Flying"', '""', '5', '"TRUE"'] 我需要将索引[6]的格式从“TRUE”改为布尔值TRUE 完整预期输出:d={'Tornadus,(化身形式)'(641,'Flying',None,5,True} 我用过: if "T" in line[6]: # format legendary if TRUE lin

使用for循环,我迭代文件中的行。鉴于这一点:

line= [ ‘641', '"Tornadus', ' (Incarnate Form)"', '"Flying"', '""', '5', '"TRUE"']
我需要将索引[6]的格式从“TRUE”改为布尔值TRUE

完整预期输出:d={'Tornadus,(化身形式)'(641,'Flying',None,5,True}

我用过:

if "T" in line[6]:  # format legendary if TRUE
    line[6] = True
但我得到了这个错误:

回溯(最近一次呼叫最后一次): 文件“tester5p.py”,第305行,在test_read_info_File_05中 self.assertEqual(read_info_文件(DATAFILE),info_db5())文件“/Users/kgreenwo/Desktop/student.py”,第52行,在read_info_文件中 第[5]行=False

TypeError:“str”对象不支持项分配

如何在for循环中分配它

要查看我的完整代码:

def read_info_file(filename):
    f = open(filename, 'r')  # open file in read mode
    d = {}  # intitialze as empty
    count = 0  # helps to skip first line
    key = ""
    for line in f:  # get each line from file
        if count != 0:  # skip first line
        # 1___________________________________________open file,read, skip 1st line
            id_num = int(line[0])  # make id an integer
        # 2________________________________________________
            if ',' in line[1]:  # two parts to fullname, changes indexes
                part1 = line[1].strip('"')  # get format first part of name
                part2 = line[2].strip()  # get format second part of name
            # 3______________
                fullname = part1 + part2
                key = fullname
            # 4______________
                type1 = line[3].strip('"')
            # 5--------------
                if line[4] == "":  # check if there is not a second type
                    type2 = None  # correct format
                else:  # is a second type
                    type2 = line[4].strip('"')  # format second type
            # 6______________

                generation = line[5]  # format generation
            # 7_____________
                if "T" in line[6]:  # format legendary if TRUE
                    line[6] = True
                    legendary = line[6]
                else:  # format legendary if FALSE
                    line[6] = False
                    legendary = line[6]

            # 8______________________________________________one part to name
            else:  # one part to name
                fullname = line[1].strip('"')
            # 9______________
                type1 = line[2].strip('"')
            # 10_____________
                if line[3] == "":  # if no second type
                    type2 = None
                else:
                    type2 = line[3].strip('"')  # there is a second type
            # 11_____________
                generation = line[4]  # format generation
            # 12_____________
                if "T" in line[5]:  # format legendary if TRUE
                    line[5] = True
                    legendary = line[5]
                else:  # formmat Legendary if False
                    line[5] = False
                    legendary = line[5]

            value = (id_num, type1, type2, generation, legendary)
            d.update([(key, value)])
        count += 1
    return d
可复制示例: 输入:(别忘了跳过第一行!)

输出: d={'Bulbasaur':(1,'Grass','Poison',1,False)}


从你的例子中不太清楚,但我的想法是:

for line in f:
    line = line.split(',')
现在,您可以处理索引并查看是否有更多错误。 如果您使用:

if "T" in line[6]:  # format legendary if TRUE
    line[6] = True

它会起作用的。

我没有重新分配它,而是这样做了,它起作用了:

if "T" in line[6]:  # format legendary if TRUE
    legendary = True
else:  # format legendary if FALSE
    legendary = False

您的输入文件看起来像一个文件。如果是,您想要的是非常简单的

假设您的输入文件是这样的:

输入文件-43644346.txt

info_file1 = '''"ID","Name","Type 1","Type 2","Generation","Legendary"
1,"Bulbasaur","Grass","Poison",1,"FALSE"
641,"Tornadus', ' (Incarnate Form)","Flying",,5,"TRUE"
"ID","Name","Type 1","Type 2","Generation","Legendary"
1,"Bulbasaur","Grass","Poison",1,"FALSE"
641,"Tornadus', ' (Incarnate Form)","Flying",,5,"TRUE"
你可以这样做:

#!/usr/bin/env python3

import csv

input_file_name = "Input_file-43644346.txt"

with open(input_file_name, newline='') as input_file:
    next(input_file)        # skip first line
    record_extractor = csv.reader(input_file)
    d = {}
    for row in record_extractor:
        key = row[1].strip()
        row_truth = row[5] == "TRUE"        # simplifying the boolean retrieving
        # Using conditional expressions
        row_second_type = row[3].strip() if row[3] else None   
        output_row = (row[0], row[2], row_second_type, row[4], row_truth)
        d[key] = output_row

print("d=", d)
以下是此解决方案的一些要点:

  • 此示例采用Python 3的语法
  • 一起使用可确保及时关闭输入文件
  • 由于文件对象也是迭代器,因此可以使用跳过第一行
  • 将为您提供一个元组,其中包含行中的信息。它将像您预期的那样处理带引号的字符串
  • 表达式
    行[5]==“TRUE”
    将生成布尔表达式。不需要使用
    if
    语句
  • 空字符串相当于False。任何其他字符串都是True
  • 可用于将空字符串更改为所需的
    None
  • 如果您已经有一个字典或元组列表,希望使用其值更新字典,但最好使用
    d[key]=value

但我猜你的文件更像这样:

#!/usr/bin/env python3

import csv

input_file_name = "Input_file-43644346.txt"

with open(input_file_name, newline='') as input_file:
    next(input_file)        # skip first line
    record_extractor = csv.reader(input_file)
    d = {}
    for row in record_extractor:
        key = row[1].strip()
        row_truth = row[5] == "TRUE"        # simplifying the boolean retrieving
        # Using conditional expressions
        row_second_type = row[3].strip() if row[3] else None   
        output_row = (row[0], row[2], row_second_type, row[4], row_truth)
        d[key] = output_row

print("d=", d)
输入文件-43644346b.txt

info_file1 = '''"ID","Name","Type 1","Type 2","Generation","Legendary"
1,"Bulbasaur","Grass","Poison",1,"FALSE"
641,"Tornadus', ' (Incarnate Form)","Flying",,5,"TRUE"
"ID","Name","Type 1","Type 2","Generation","Legendary"
1,"Bulbasaur","Grass","Poison",1,"FALSE"
641,"Tornadus', ' (Incarnate Form)","Flying",,5,"TRUE"
然后,您可以使用来读取数据:

#!/usr/bin/env python3

import csv

input_file_name = "Input_file-43644346b.txt"

with open(input_file_name, newline='') as input_file:
    record_extractor = csv.DictReader(input_file)
    d = {}
    for row in record_extractor:
        key = row["Name"].strip()
        row_truth = row["Legendary"] == "TRUE"
        row_second_type = row["Type 2"].strip() if row["Type 2"] else None
        output_row = (row["ID"], row["Type 1"],
                      row_second_type, row["Generation"], row_truth)
        d[key] = output_row

print("d=", d)
这使您能够使用“列”名称来标识每行的不同部分


通过使用以下理解,您可以进一步简化代码:

#!/usr/bin/env python3

import csv

input_file_name = "Input_file-43644346.txt"

with open(input_file_name, newline='') as input_file:
    next(input_file)        # skip first line
    record_extractor = csv.reader(input_file)
    d = { row[1]: (row[0],
                   row[2],
                   row[3].strip() if row[3] else None,
                   row[4],
                   row[5] == "TRUE")
          for row in record_extractor }

print("d=", d)

您需要提供一个可复制的示例。您的
line
示例不是有效的Python,您的意思似乎是要将其列为一个列表,在这种情况下,它不会抛出该错误。我不知道是否是因为您键入了它,而是第一个引号“”是一个不同的符号。当我将上面的代码复制到python解释器中时,它表示“641”之后的所有内容都是字符串。我添加了完整的代码,以便您可以看到我在做什么。它被注释以便于澄清。行列表是在我使用read()时创建的。该列表中的所有内容都成为字符串。我必须将必要的元素转换为所需的输出。是的,问题是
是一个
str,因为它在文件处理程序上迭代。索引到字符串中会给出该位置的字符,例如
“hello”[1]=='e'
。您不能分配给字符串。我认为您想用逗号分割行…并且您还没有提供一个可复制的示例。对,正如我所怀疑的,您正在使用某个值分隔的文件,即csv,但是当您逐行迭代该文件时,
是一个字符串。当您索引到字符串中时,您将索引您假定
是一个基于文件中分隔符的字符串列表…即使使用您的方法,也会返回:['641','Tornadus','(化身形式)','Flying','TRUE','5']