搜索文件并从行返回必填字段的最佳方法

时间:2017-07-20 15:57:53

标签: python file csv search

我有以下完美的代码。它在txt文件中搜索ID号,如果存在,则返回名字和姓氏。

完整列表:https://repl.it/Jau3/0

import csv

#==========Search by ID number. Return Just the Name Fields for the Student
with open("studentinfo.txt","r") as f:
  studentfileReader=csv.reader(f)
  id=input("Enter Id:")
  for row in studentfileReader:
    for field in row:
      if field==id:
        currentindex=row.index(id)
        print(row[currentindex+1]+" "+row[currentindex+2])

文件内容

001,Joe,Bloggs,Test1:99,Test2:100,Test3:33
002,Ash,Smith,Test1:22,Test2:63,Test3:99

出于教学目的,我想知道是否有其他方法可以达到同样的目的(优雅,简单,pythonic),或者这可能是最好的解决方案吗?

我的问题源于这样一个事实,即可能有一个内置方法或某些函数可以更有效地检索当前索引并搜索字段.....可能不是。

提前感谢您的讨论以及我将接受的任何解释作为答案。

4 个答案:

答案 0 :(得分:1)

如果列表保留了这种格式,你可以按索引访问该行的字段以稍微压缩它。

for row in studentfileReader:
    if row[0]==id:
        print(row[1]+" "+row[2])

如果ID不在开头但在某处介于两者之间,它也可以避免匹配。 “测试1:002”

答案 1 :(得分:1)

我真的不知道是否存在在匹配键上找到记录的“pythonic”方式,但这里有一个例子,在你自己的例子和其他答案上添加了几个有趣的东西,比如发电机的使用和理解。此外,什么是比一个班轮更pythonic。

any是一个内置的python,它可能会让你知道它存在,因为它完全与你做的一样。

with open("studentinfo.txt","r") as f:
    sid=input("Enter Id:")
    print any((line.split(",")[0] == sid for line in f.readlines()))

答案 2 :(得分:1)

您应该考虑使用csv.DictReader来实现此用途,因为您的表格数据具有一致的列。

如果您只想检索一次数据,那么您可以简单地遍历文件,直到第一次出现所需的ID,如下所示;

import csv

def search_by_student_id(id):
    with open('studentinfo.txt','r') as f:
        reader = csv.DictReader(f, ['id', 'surname', 'first_name'],
                                restkey='results')
        for line in reader:
            if line['id'] == id:
                return line['surname'], line['first_name']

print(search_by_student_id('001'))
# ('Joe', 'Bloggs')

但是,如果您计划多次从此数据中查找条目,则创建字典会付出代价,而字典的创建成本更高,但会显着缩短查找时间。然后你可以查找这样的数据;

def build_student_id_dict():
    with open('studentinfo.txt','r') as f:
        reader = csv.DictReader(f, ['id', 'surname', 'first_name'],
                                restkey='results')
        student_id_dict = {}
        for line in reader:
            student_id_dict[line['id']] = line['surname'], line['first_name']
        return student_id_dict

student_by_id_dict = build_student_id_dict()
print(student_by_id_dict['002'])
# ('Ash', 'Smith')

答案 3 :(得分:0)

您可以将其读入列表,或者在查找时间方面更好地阅读字典,然后只需使用以下内容:

如果在l ,如果在d (l或d分别是列表/词典)

然而,有趣的讨论是,这是最简单的方法,还是现有的解决方案。

<强>字典:

   1 # retrieve the value for a particular key
   2 value = d[key]

关于使用词典的时间复杂性和效率的说明:

在给定特定密钥对象的情况下,Python映射必须能够确定哪个(如果有)值对象与给定密钥相关联。一种简单的方法是存储(键,值)对的LIST,然后在每次请求值时按顺序搜索列表。您可以立即看到这对于大量项目来说会非常慢 - 在复杂性方面,此算法将为O(n),其中n指的是映射中的项目数。

Python的字典就是这里的答案,虽然它并不总是最好的解决方案 - 通过要求密钥对象提供“哈希”,实现将字典查找的平均复杂性降低到O(1) “功能。在你的情况下,因为在结构上你正在处理的数据并不是非常复杂,所以最简单的方法就是坚持你现有的解决方案,尽管如果时间效率很高,你肯定应该考虑字典。