简体   繁体   English

在使用 readlines 和 .split() 函数时,使用 for 循环进行迭代会更容易吗?

[英]While using readlines and .split() function, would it be easier to iterate through with for-loop?

I've created a while loop to iterate through, read the data.txt file, calculate the perimeter/area/vertices, and the root will print out the answers.我创建了一个 while 循环来迭代,读取 data.txt 文件,计算周长/面积/顶点,然后根将打印出答案。

I'm stuck here:我被困在这里:

from Polygon import Polygon
from Rectangle import Rectangle

in_file = open('data.txt', 'r')

line = in_file.readlines()

while line:
    type_, num_of_sides = line.split( ) ###ERROR 'list' object has no attribute 'split'

    sides = [map(float, in_file.readline().split()) for _ in range(int(num_of_sides))]
    print(line)

    if type_ == 'P':
        poly_object = Polygon(sides)

    elif type_ == 'R':
        poly_object = Rectangle(sides)

    print('The vertices are {}'.format(poly_object.vertices))
    print('The perimeter is {}'.format(poly_object.perimeter()))
    print('The area is {}'.format(poly_object.area()))
    print()

    line = in_file.readline()

in_file.close()

Should I create a for loop that loops through since readlines is a list of strings and I want the split to read through each line?我应该创建一个循环的for循环,因为readlines是一个字符串列表,我希望拆分读取每一行? Or is it just the way that I'm choosing to format, so that's why I'm getting an error?或者这只是我选择格式化的方式,所以这就是我收到错误的原因?

The immediate issue is use of readlines , not readline in line = in_file.readlines() .当前的问题是使用readlines ,而不是line = in_file.readlines() readline This will populate line with a list of all lines from the file, rather than a single line.这将使用文件中所有行的列表填充line ,而不是单行。 This will lead to two issues with your program where the wrong type of data will propagate through the loop:这将导致您的程序出现两个问题,其中错误类型的数据将通过循环传播:

  1. Calling while line , in this instance, after reading a non-empty file will cause the loop to be executed, because a non-empty list evaluates to true.在这种情况下,在读取非空文件后调用while line将导致执行循环,因为非空列表的计算结果为 true。
  2. You call split on line .您在line上调用split On the first iteration of the loop, line contains a list of strings (where each string was a line in the file).在循环的第一次迭代中, line包含一个字符串列表(其中每个字符串都是文件中的一行)。 Lists to do not have a split method – only the individual strings do.列表没有split方法——只有单个字符串有。 This call fails.此调用失败。
  3. If the call to split had not failed and the loop had been allowed to run through once, the subsequent call to line = in_file.readline() would not return the next line in the file, as all lines have been read by the earlier call to readlines and the cursor not reset in the intervening period from EOF.如果对split的调用没有失败并且允许循环运行一次,则对line = in_file.readline()的后续调用将不会返回文件中的下一行,因为之前的调用已读取所有行从 EOF 到readlines和光标不在中间期间重置。 The loop will terminate.循环将终止。

If you did not have the final call in step 3, the loop would instead run forever without termination, as the value of line would never be updated to be a non-empty list.如果您没有在第 3 步中进行最终调用,则循环将永远运行而不终止,因为line的值永远不会更新为非空列表。


A minimal change is to adjust the initial call which assigns a value to the line variable to readline() rather than readlines() to ensure only a single line is read from the file.的最小变化是要调整的一个值分配给初始呼叫line变量readline()而不是readlines()以确保只有一个单一的线被从文件中读取。 The logic in the code should then work.然后代码中的逻辑应该可以工作。


You may find the following implementation logic easier to implement and reason about:您可能会发现以下实现逻辑更容易实现和推理:

  • collect the machinery for reading from in_file together into a single block before the loop, using a context manager to automatically close the file on leaving the block在循环之前将用于从in_file读取的机器收集到单个块中,使用上下文管理器在离开块时自动关闭文件
  • producing a list of lines, which a simple for loop is sufficient to iterate over生成一个行列表,一个简单的for循环就足以迭代
# This context manager will automatically ensure `in_file` is closed
# on leaving the `with` block.
with open('data.txt', 'r') as in_file:
    lines = in_file.readlines()

for line in lines:
    # Do something with each line; in particular, you can call
    # split() on line without issue here.
    #
    # You do not require any further calls to in_file.readline()
    # in this block.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM