【问题标题】:How to read line by line and parse from a file in python?如何逐行读取并从python中的文件中解析?
【发布时间】:2012-09-26 22:57:54
【问题描述】:

如何在python中逐行读取并解析文件?

我是 python 新手。

输入的第一行是模拟次数。 下一行是行数 (x),后跟一个空格,然后是列数 (y)。 下一组 y 行将有 x 个字符,其中一个句点 ('.') 代表一个空格,一个大写字母“A”代表一个起始代理。

我的代码出错了

Traceback (most recent call last):
    numSims = int (line)
TypeError: int() argument must be a string or a number, not 'list'

感谢您的帮助。

输入.txt

2   --- 2 simulations
3 3  -- 3*3 map
.A.  --map
AA.
A.A
2 2  --2*2 map
AA  --map
.A
def main(cls, args):
    numSims = 0
    path = os.path.expanduser('~/Desktop/input.txt') 
    f = open(path) 
    line = f.readlines() 
    numSims = int (line)
    print numSims
    k=0
    while k < numSims:
        minPerCycle = 1
        row = 0
        col = 0
        xyLine= f.readLines()
        row = int(xyLine.split()[0]) 
        col = int(xyLine.split()[1])
        myMap = [[Spot() for j in range(col)] for i in range(row)] 
        ## for-while
        i = 0
        while i < row:
            myLine = cls.br.readLines()
            ## for-while
            j = 0
            while j < col:
                if (myLine.charAt(j) == 'B'):
                    cls.myMap[i][j] = Spot(True)
                else:
                    cls.myMap[i][j] = Spot(False)
                j += 1
            i += 1

对于 Spot.py

Spot.py

class Spot(object):
isBunny = bool()
nextCycle = 0
UP = 0
RIGHT = 1
DOWN = 2
LEFT = 3
SLEEP = 4

def __init__(self, newIsBunny):
    self.isBunny = newIsBunny
    self.nextCycle = self.UP

【问题讨论】:

  • 那么,给出的代码有什么问题?
  • 你应该试试 atpy 模块——它很容易读入和解析列,你所要做的就是指定文件类型(在这种情况下为 ascii)和分隔符。
  • @Mike:关于你的 Spot 类......我认为你仍然对 Python 类的工作方式有误解。请不要试图伪造变量的类型声明,它们既不需要也不能阻止,例如这个:s = Spot(7); s.isBunny = 'joe'

标签: python parsing readline


【解决方案1】:

Martijn Pieters does a very good job 在解释如何使您的代码变得更好时,我建议采用完全不同的方法,即使用 Monadic Parser Combinator 库,例如Parcon。这使您可以超越上下文无关语法,并在运行时根据当前解析过程提取的信息轻松修改解析器:

from functools import partial
from parcon import (Bind, Repeat, CharIn, number, End,
                    Whitespace, ZeroOrMore, CharNotIn)

def array(parser, size):
    return Repeat(parser, min=size, max=size)

def matrix(parser, sizes):
    size, sizes = sizes[0], sizes[1:]
    return array(matrix(parser, sizes) if sizes else parser, size)

comment = '-' + ZeroOrMore(CharNotIn('\n')) + '\n'

sims = Bind(number[int],
            partial(array,
                    Bind(number[int] + number[int],
                         partial(matrix,
                                 CharIn('.A')['A'.__eq__])))) + End()

text = '''
2   --- 2 simulations
3 3  -- 3*3 map
.A.  --map
AA.
A.A
2 2  --2*2 map
AA  --map
.A
'''

import pprint
pprint.pprint(sims.parse_string(text, whitespace=Whitespace() | comment))

结果:

$ python numsims.py
[[False, True, False], [True, True, False], [True, False, True]]
[[True, True], [False, True]]

一开始它有点让人费解,就像所有单子的东西一样。但是表达的灵活性和简洁性非常值得花时间学习单子。

【讨论】:

    【解决方案2】:

    您的错误很多,以下是我目前发现的错误:

    1. numSims = (int)line 行并没有像你认为的那样做。 Python 没有 C 类型转换,您需要 调用 int 类型:

      numSims = int(line)
      

      您稍后使用Int 的大写拼写来复合此错误:

      row = (Int)(xyLine.split(" ")[0])
      col = (Int)(xyLine.split(" ")[1])
      

      以类似的方式更正这些:

      row = int(xyLine.split()[0])
      col = int(xyLine.split()[1])
      

      由于.split() 的默认值是在空格上分割,您可以省略" " 参数。更好的是,将它们组合成一行:

      row, col = map(int, xyLine.split())
      
    2. 您永远不会增加 k,因此您的 while k &lt; numSims: 循环将永远持续下去,因此您将收到 EOF 错误。改用for 循环:

      for k in xrange(numSims):
      

      你不需要在这个函数的任何地方使用while,它们都可以用for variable in xrange(upperlimit):循环替换。

    3. Python 字符串没有.charAt 方法。请改用[index]

      if myLine[j] == 'A':
      

      但由于 myLine[j] == 'A' 是一个布尔测试,您可以像这样简化您的 Spot() 实例化:

      for i in xrange(row):
          myLine = f.readLine()
          for j in xrange(col):
              cls.myMap[i][j] = Spot(myLine[j] == 'A')
      
    4. 在 Python 中不需要太多初始化变量。如果您要在下一行分配新值,您可以获得大部分 numSims = 0col = 0 行等。

    5. 您改为创建一个“myMapvariable but then ignore it by referring tocls.myMap”。

    6. 这里没有处理多重映射;文件中的最后一张地图会覆盖之前的任何地图。

    改写版:

    def main(cls, args):
        with open(os.path.expanduser('~/Desktop/input.txt')) as f:
            numSims = int(f.readline())
            mapgrid = []
            for k in xrange(numSims):
                row, col = map(int, f.readline().split())  
                for i in xrange(row):
                    myLine = f.readLine()
                    mapgrid.append([])
                    for j in xrange(col):
                        mapgrid[i].append(Spot(myLine[j] == 'A'))
             # store this map somewhere?
             cls.myMaps.append(mapgrid)
    

    【讨论】:

    • 哇,对一些有问题的代码进行了惊人的彻底分析。 . .干得好!
    • 抱歉,我把变量命名为 map 是我的错误。已更正。
    猜你喜欢
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    • 1970-01-01
    • 2018-01-26
    • 2015-05-21
    • 1970-01-01
    • 2012-04-12
    • 2019-04-16
    相关资源
    最近更新 更多