【问题标题】:Finding a line in a file then reading next few lines in Python在文件中查找一行,然后在 Python 中读取接下来的几行
【发布时间】:2013-04-21 01:22:40
【问题描述】:

我有一个包含以下数据的纯文本文件:

id=1
name=Scott
occupation=Truck driver
age=23

id=2
name=Dave
occupation=Waiter
age=16

id=3
name=Susan
occupation=Computer programmer
age=29

我正在尝试找出在给定id 字符串的情况下到达文件中任何点的最佳方法,然后抓取下面的行以提取数据以在我的程序中使用。我可以这样做:

def get_person_by_id(id):
    file = open('rooms', 'r')
    for line in file:
        if ("id=" + id) in line:
            print(id + " found")

但我不确定我现在如何通过下一行并执行line.split("=") 或类似操作来提取我可以使用我的程序的信息(放入列表或字典或其他任何内容)。有什么指点吗?

【问题讨论】:

  • 每个 ID 的所有数据是否都可用,或者某些记录的信息可能比其他记录少?
  • 很大程度上取决于您对格式的了解。每个条目总是4行吗?可以有其他的钥匙吗?基本上,你可以多次拨打file.readline()
  • 你能/愿意改变文件格式吗?如果可以的话,你可以使用 csv 模块。见这里:docs.python.org/2/library/csv.html。也许您也可以让 csv 模块也适用于这种情况。

标签: python


【解决方案1】:

一种选择是将整个内容加载到内存中,这样可以避免您每次都读取文件:

with open('rooms') as f:
    chunks = f.read().split('\n\n')

people_by_id = {}

for chunk in chunks:
    data = dict(row.split('=', 1) for row in chunk.split('\n'))
    people_by_id[data['id']] = data
    del data['id']

def get_person_by_id(id):
    return people_by_id.get(id)

【讨论】:

  • 如果文件非常大,最好不要将整个文件读入内存,而是在特定行停止文件处理。其他一些答案提供了这样的解决方案。
【解决方案2】:

找到正确的行后如何退出for循环:

def get_person_by_id(id):
    file = open('rooms', 'r')
    for line in file:
        if ("id=" + id) in line:
            print(id + " found")
            break
    #now you can continue processing your file:
    next_line = file.readline()

【讨论】:

    【解决方案3】:

    也许:

    d = dict()
    
    with open(filename) as f:
        for line in f:
            k,v = line.split('=')
            if 'id=' in line:
                d[v] = {}
            d[d.keys()[-1]][k] = v
    

    【讨论】:

      【解决方案4】:

      这是一个迭代解决方案。

      objects = []
      current_object = None
      with open("info.txt", "rb") as f:
          for line in f:
              line = line.strip("\r\n")
              if not line:
                  current_object = None
                  continue
              if current_object is None:
                  current_object = {}
                  objects.append(current_object)
              key,_,value = line.partition('=')
              current_object[key] = value
      
      print objects
      

      【讨论】:

        【解决方案5】:

        迭代解析器的另一个例子:

        from itertools import takewhile
        def entries(f):
            e = {}
            def read_one():
                one = {}
                for line in takewhile(lambda x: '=' in x, f):
                    key, val = line.strip().split('=')
                    one[key] = val
                return one
            while True:
                one = read_one() 
                if not one:
                    break
                else:
                    e[one.pop('id')] = one
            return e
        

        例子:

        >>> with open('data.txt') as f:
        ..:    print entries(f)['2']
        {'age': '16', 'occupation': 'Waiter', 'name': 'Dave'}
        

        【讨论】:

          【解决方案6】:

          获取该人的所有属性和值( id、姓名、职业、年龄等),直到找到 一个空行。

          def get_person_by_id(id):
              person = {}
              file = open('rooms', 'r')
              for line in file:
                  if found == True:
                      if line.strip():
                          attr, value = line.split("="):
                      else:
                          return person              
                  elif ("id=" + id) in line:
                      print(id + " found")
                      found = True
                      attr, value = line.split("=")
                      person[attr] = value
              return person
          

          【讨论】:

            【解决方案7】:

            此解决方案对记录中的空行更加宽容。

            def read_persons(it):
                person = dict()
                for l in it:
                    try:
                        k, v = l.strip('\n').split('=', 1)
                    except ValueError:
                        pass
                    else:
                        if k == 'id': # New record
                            if person:
                                yield person
                                person = dict()
                        person[k] = v
                if person:
                    yield person
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-03-23
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-08-01
              • 1970-01-01
              相关资源
              最近更新 更多