根据其他列表值查找替换列表值

时间:2019-02-14 04:51:43

标签: python

我正在为学校做作业,但是碰壁了。

挑战在于:

您将获得文件名P,名字F,姓氏L和新的生日B。

将定长记录文件加载到P中,首先搜索F,L,然后将生日更改为B。

然后保存文件。


我设法从文件中读取并将数据分成列表中所需的条目。
但是,当我在列表中搜索名字和姓氏时,就会出现问题。
传递的名字和姓氏是Adam Smith,但在列表中也有一个Adam Smithers,我的代码也找到了该人。 当我尝试替换列表中所需的元素时,它将同时替换为Smith和Smithers。

我们不能使用正则表达式进行赋值,因此在不使用正则表达式而忽略包含Smith的其他姓氏的同时,如何处理此问题并找到与姓氏的完全匹配项,我有些茫然。

这是我的代码:

import sys

P= sys.argv[1] 
F= sys.argv[2]
L= sys.argv[3]
B= sys.argv[4]

filePath = P
firstName = F
lastName = L
newBirthday = B
records = []

file1 = open(filePath, 'r')
fileContent = file1.read()

while len(fileContent) > 0:
  record = []
  fname = fileContent[0:16]
  lname = fileContent[16:32]
  bday = fileContent[32:40]
  record = [fname,lname,bday]
  records.append(record)
  fileContent = fileContent[40:]

for record in records:
  if firstName in record[0] and lastName in record[1]:
    record[2] = newBirthday

file1.close()

file2 = open(filePath, 'w')

for record in records:
  file2.write(record[0])
  file2.write(record[1])
  file2.write(record[2])

file2.close()

任何人能够提供的任何想法或暗示都会受到赞赏。

谢谢!

编辑:

冰酒足以建议使用以下内容:

if firstName == record[0] and lastName == record[1]:

但是,当我尝试这样做时,它找不到任何匹配的记录。

我相信这是因为每个名称后都有空白,以使每个名称中包含16个字符,从而使名称具有固定的长度。因此,当我使用==运算符时,它找不到完全匹配,因为名称中也有空格,因此不是完全匹配。

5 个答案:

答案 0 :(得分:1)

使用==代替

 if firstName == record[0] and lastName == record[1]:

编辑:试试这个

从字符串末尾删除空格

 if firstName.rstrip() == record[0].rstrip() and lastName.rstrip() == record[1].rstrip()

从字符串的开头和结尾删除空格

 if firstName.strip() == record[0].strip() and lastName.strip() == record[1].strip()

答案 1 :(得分:1)

修剪字符串中的空格,然后使用==进行匹配。这将给出预期的输出。示例代码

for record in records:
  if firstName == record[0].strip() and lastName == record[1].strip():
    record[2] = newBirthday

答案 2 :(得分:1)

在填充的数据上填充两个空格以匹配文件中的内容:

firstName = f'{F:<16}'

或从文件内容中删除多余的空格以匹配传递的数据:

fname = fileContent[0:16].strip()

然后,您可以简单地比较名称,保留in运算符或使用==

答案 3 :(得分:0)

一个简单的解决方案是对名称和值的列表进行排序(在这种情况下,生日(我建议您为此目的使用字典)),然后执行搜索操作,仅查找元素的首次出现。这样只能选择Adam Smith

然后,您可以通过检查下一个元素是否与找到的元素相同来进一步处理重复项。

即如果第一次出现是i,请检查是否i+1 == i,并更新所有重复项。 (这可能是您需要做的运动,尽管像这样更新其他人的生日没有意义。)

希望这会有所帮助:)

答案 4 :(得分:0)

以下是我可以对您的代码提出的一些改进建议:

  • 创建一个函数或至少将代码放入if __name__ == '__main__':中。您可以在Google上搜索原因。
  • 我建议使用with open(file_path, 'r') as f:读写文件;看起来更干净,并且您不会忘记关闭文件。
  • 在与您的输入进行比较之前删除周围的空间;我使用了line[:16].strip()
  • 您以指定的宽度读取,因此不要忘记以相同的宽度写回文件。此代码确保记录的每个部分都具有指定的宽度:

    f.write('{:16s}{:16s}{:8s}'.format(*record))
    

这是我的代码版本:

import sys

if __name__ == '__main__':
    file_path = sys.argv[1]
    first_name = sys.argv[2]
    last_name = sys.argv[3]
    new_birth_date = sys.argv[4]

    record_list = []

    with open(file_path, 'r') as f:
        while True:
            line = f.read(40)               # read 40 chars at the time
            if len(line) == 0:
                # the end of the file was reached
                break

            record = [
                line[:16].strip(),
                line[16:32].strip(),
                line[32:].strip(),
            ]
            if first_name == record[0] and last_name == record[1]:
                record[2] = new_birth_date

            record_list.append(record)

    with open(file_path, 'w') as f:
        for record in record_list:
            f.write('{:16s}{:16s}{:8s}'.format(*record))

这对您有用吗?


注意:此代码不会按换行符分隔行,但它一次读取40个字符,因此您可能最终在这40个字符中使用换行符。

之所以这样做是因为问题中的代码似乎做了类似的事情。