如何检查和更改文本文件中的值?(Python 2.7.11)

如何检查和更改文本文件中的值?(Python 2.7.11),python,Python,已解释的文本文件: Joe,Bloggs,J.bloggs@anemailaddress.com,01269512355, 1 ,0, 0, 0, 0 Fname, Lname, Email, number, Value i want checking ^ , ...,...,...,... 目标:检查键的值[4]中的数字是否不是0或7。 如果为0,则变为1;如果为7,则变为6。 如果是0,那么是+1,如果是7,那么是-1 文本文件: Joe,Bloggs,J.bloggs@anemaila

已解释的文本文件:

Joe,Bloggs,J.bloggs@anemailaddress.com,01269512355, 1 ,0, 0, 0, 0
Fname, Lname, Email, number, Value i want checking  ^ , ...,...,...,...
目标:检查键的值[4]中的数字是否不是0或7。 如果为0,则变为1;如果为7,则变为6。 如果是0,那么是+1,如果是7,那么是-1

文本文件:

Joe,Bloggs,J.bloggs@anemailaddress.com,01269512355, 1,0, 0, 0, 0
Sarah,Brown,S.brown@anemailaddress.com,01866522555, 5,0, 0, 0, 0
Andrew,Smith,A.smith@anemailaddress.com,01899512785, 7,0, 0, 0, 0
Kevin,White,K.white@anemailaddress.com,01579122345, 0,0, 0, 0, 0
Samantha,Collins,S.collins@anemailaddress.com,04269916257, 0,0, 0, 0, 0
代码运行后,应如下所示:

Joe,Bloggs,J.bloggs@anemailaddress.com,01269512355, 1,0, 0, 0, 0
Sarah,Brown,S.brown@anemailaddress.com,01866522555, 5,0, 0, 0, 0
Andrew,Smith,A.smith@anemailaddress.com,01899512785, 6,0, 0, 0, 0
Kevin,White,K.white@anemailaddress.com,01579122345, 1,0, 0, 0, 0
Samantha,Collins,S.collins@anemailaddress.com,04269916257, 1,0, 0, 0, 0
到目前为止,我的代码产生了一个错误:

fileinfo[j] = i[0] + ',' + i[1] + ',' + i[2] + ',' + i[3] + ',' + str(value) + ',' + i[5] + ',' + i[6] + ',' + i[7]+ ',' + i[8] + '\n'
IndexError: list assignment index out of range
代码:

这可能是做我想做的事情的一种非常复杂的方式。你能帮我实现我的目标吗。请随意重写我的全部代码,但您能详细解释一下您所做的工作吗。我对编码相当陌生

给未来的读者


有两个答案是有效的。我只能勾选其中一个。希望这个问题能像我一样帮助未来的读者

在循环中每次递增
j
两次,此时它应该跟踪每行的位置,因此它变得太大并导致错误。

以下是代码的简化版本(完全未经测试)


您的代码存在以下问题:

  • 在将数字转换为整数之前,应删除数字周围的空格:
    value=int(i[4])
    如果数字周围有空格,则会崩溃。使用
    value=int(i[4].strip())
    修复此问题

  • 将值转换为整数,然后将该整数与字符串进行比较。这将始终计算为
    False

    value=int(i[4])
    如果值==“0”:

  • 每个循环增加两次
    j
    ,这就是代码与索引器崩溃的原因。我建议使用而不是手动维护
    j

  • 固定代码可能如下所示:

    for j, i in enumerate(fileinfo):
        i = i.strip()
        i = i.split(",")
        value = i[4].strip()
        if value == "0":
            i[4] = "1"
        elif value == "7":
            i[4] = "6"
        fileinfo[j] = ','.join(i) + '\n'
    
    这意味着:

    假设您在
    fileinfo
    中有三行代码:['aaa','bbb','ccc']
    在第一次循环迭代中,您有
    i='aaa'
    j=0
    <代码>文件信息[0]指向第一行。
    在第二次迭代中,
    i='bbb'
    j=2
    <代码>文件信息[2]指向第三行。
    在第三次迭代中,
    i='ccc'
    j=4
    。您尝试读取不存在的第五行(
    fileinfo[4]


    每个循环迭代只增加
    j
    的值一次,并且
    i
    /
    j
    将保持同步。

    以下是代码的更正版本(解释如下)。我试着做尽可能少的改变

    f = open("players.txt","r")
    fileinfo = f.readlines()
    f.close()
    
    for i in enumerate(fileinfo):
        i[1] = i[1].strip()
        i[1] = i[1].split(",")
        #Make sure we don't go out of range, if so, skip to the next line.
        if len(i[1]) < 5:
            continue
        value = int(i[1][4].strip())
        if value == 0:
            value += 1
        elif value == 7:
            value -= 1
    
        i[1][4] = str(value)
        fileinfo[i[0]] = ",".join(i)
    
    f = open("players.txt","w")
    f.write("\n".join(fileinfo))
    f.close()
    
    f=open(“players.txt”、“r”)
    fileinfo=f.readlines()
    f、 关闭()
    对于枚举中的i(文件信息):
    i[1]=i[1].strip()
    i[1]=i[1]。拆分(“,”)
    #确保我们没有超出范围,如果超出范围,请跳到下一行。
    如果len(i[1])<5:
    持续
    value=int(i[1][4].strip())
    如果值==0:
    值+=1
    elif值==7:
    值-=1
    i[1][4]=str(值)
    fileinfo[i[0]]=“,”。加入(i)
    f=打开(“players.txt”、“w”)
    f、 写入(“\n”.join(fileinfo))
    f、 关闭()
    
  • value
    是一个int,但您将其与字符串进行比较
  • j
    不是必需的,我用
    enumerate
    函数替换了它。这将创建供您使用的[索引,值]对
  • 您检查了两次
    value
    ,设置了两次
    i
    。我通过清理if块并利用
    elif
    纠正了这个问题
  • .join
    方法为您节省了大量工作。它从一个带有删除器的列表中创建一个字符串<代码>''。加入(['Hello','world!'])成为
    你好世界
  • 如果有任何行太短,则会出错(例如空行)。我添加了一个检查,在这种情况下,它将利用
    continue
    跳过该行
  • 在尝试转换为int之前,应该去掉元素周围的空白
  • 在添加值时,通常更容易使用
    +=
    -=

  • Scott Hunter正在写你在循环中错误地增加了两次
    j
    。此外,您可能还希望将整个内容写得更具可读性,例如:

    filename = 'players.txt'
    
    with open(filename, 'r') as f:
        lines = f.readlines()
    
    output = []
    
    for line in lines:
        split_line = line.split(',')
        split_line = map(str.strip, split_line)
    
        num = split_line[4]
    
        if num == '0':
            split_line[4] = '1'
        if num == '7':
            split_line[4] = '6'
    
        output.append(','.join(split_line))
    
    with open(filename, 'w') as f:
        f.write('\n'.join(output))
    

    假设你不喜欢逗号之间的空格。

    对不起,我不太明白你的意思。你是说我应该删除或添加逗号吗?我把每一行的成分都算错了;真正的问题是在循环中每次递增两次
    j
    。您需要
    ,'。join(i)
    从由“,”删除的列表中创建一个字符串。另外,您还应该看看
    枚举
    函数,以消除对
    j
    @Dot\u Py:的需要,仅在python2中,只要
    f
    是一个类似文件的对象。哎呀,我不必这么做。。更新。谢谢好吧,我输入密码时打错了。一切都好了,哈哈。谢谢你努力帮助我。谢谢。@Toby:你可能有一条空行,这可能会导致它断开。检查更新的代码。你不应该有新文件。代码读取和写入同一个文件。清理您的环境,然后重试:)谢谢你解释为什么我的代码不起作用。我已经试过你的代码,它工作得很好。谢谢你努力帮助我。谢谢你的解释。现在对我来说更有意义了。
    j = 0
    for i in fileinfo:
        # Do something on fileinfo[j]
        j = j + 1
    
        # Do something on fileinfo[j]
        j = j + 1
    
    f = open("players.txt","r")
    fileinfo = f.readlines()
    f.close()
    
    for i in enumerate(fileinfo):
        i[1] = i[1].strip()
        i[1] = i[1].split(",")
        #Make sure we don't go out of range, if so, skip to the next line.
        if len(i[1]) < 5:
            continue
        value = int(i[1][4].strip())
        if value == 0:
            value += 1
        elif value == 7:
            value -= 1
    
        i[1][4] = str(value)
        fileinfo[i[0]] = ",".join(i)
    
    f = open("players.txt","w")
    f.write("\n".join(fileinfo))
    f.close()
    
    filename = 'players.txt'
    
    with open(filename, 'r') as f:
        lines = f.readlines()
    
    output = []
    
    for line in lines:
        split_line = line.split(',')
        split_line = map(str.strip, split_line)
    
        num = split_line[4]
    
        if num == '0':
            split_line[4] = '1'
        if num == '7':
            split_line[4] = '6'
    
        output.append(','.join(split_line))
    
    with open(filename, 'w') as f:
        f.write('\n'.join(output))