如何循环直到从文件中读取所有行?

2024-04-19 06:12:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试建立一个计分系统,在这个系统中,我需要将文本文件中的所有分数输入一个“记录数组”。你知道吗

我对Python相当陌生,希望有一个简单的解决方案。你知道吗

在我的程序中,从技术上讲,记录数组将分类为namedtuples列表。你知道吗

目前我有:

Player = namedtuple("Player", ["name", "result", "difficulty", "score"])

Playerlist = []
while str(f.readline) != '':
    player = Player(
        f.readline(),
        f.readline(),
        f.readline(),
        f.readline())
    Playerlist.append(player)

我试着print(Playerlist[0]),但什么也没出现。你知道吗

我也尝试过print(Playerlist[0])不使用任何循环,并得到了预期的结果,尽管我不会将文本文件中的所有数据都存储到我的程序中。你知道吗

文本文件(scores.txt)中的内容示例:

George
lost
H
18
Holly
lost
H
28
Marcus
won
H
30

编辑: 我试过:

with open("scores.txt", "r") as f:
    for line in f:
        player = Player(
            f.readline(),
            f.readline(),
            f.readline(),
            f.readline())
        Playerlist.append(player)

但是所有的内容都混在一起了:

Player(name='H\n', result='28\n', difficulty='Marcus\n', score='won\n')

Tags: name程序readline系统记录数组resultscore
2条回答

这个代码和这个方法都有几个问题。有许多文件格式对这类事情很有用;一种非常流行的具有内置Python支持的格式是JSON。你知道吗

import json
from pprint import pprint


old_players = [
    {
        'name': 'Bob',
        'result': 'success?',
        'difficulty': 'hard',
        'score': 55,
    },
    {
        'name': 'Tatsuki',
        'result': 'embarrassment',
        'difficulty': 'easy',
        'score': -2,
    },
]

with open('player-file.json', 'w') as outfile:
    outfile.write(json.dumps(old_players))

with open('player-file.json', 'r') as infile:
    new_players = json.loads(infile.read())

pprint(new_players)
# [{'difficulty': 'hard', 'name': 'Bob', 'result': 'success?', 'score': 55},
#  {'difficulty': 'easy', 'name': 'Tatsuki', 'result': 'embarrassment', 'score': -2}]

namedtuple不是我经常看到的东西。将它与JSON一起使用可能有点不可靠,虽然有workarounds,但最好使用带有简单自定义序列化程序的Player类,将由namedtuple生成的类作为子类,该类定义返回JSON或JSON formattable dict的方法(非常复杂),或者编写一个单独的函数,将namedtuple对象显式转换为JSON。你知道吗

关于阅读现有格式:

from pprint import pprint
from collections import namedtuple


Player = namedtuple("Player", ["name", "result", "difficulty", "score"])


def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]


with open('/tmp/players.old', 'r') as infile:
    lines = [l.strip() for l in infile.readlines()]

for player_values in chunks(lines, 4):
    pprint(Player(*player_values))

# Player(name='George', result='lost', difficulty='H', score='18')
# Player(name='Holly', result='lost', difficulty='H', score='28')
# Player(name='Marcus', result='won', difficulty='H', score='30')

chunks函数来自this answer。这取决于你知道每个玩家要解包的值的数量,对于这种格式是不能改变的。你知道吗

在这里读取lines时,使用list comprehension从每个值的末尾剥离换行符。你知道吗

最后,用player_values实例化Player元组,这是一个由chunks生成并使用*展开的列表。这意味着,不是将列表player_values传递给函数Player.__init__(...),而是将单个值作为^{}发送。因此,有效地,方法调用变成了Player(name, result, difficulty, score),而不是Player([name, result, difficulty, score])。你知道吗

虽然这从技术上来说是检索值的,但是请注意这里分配的score是一个字符串,而不是一个数值。例如,如果希望将其转换为int,则需要写出完整的实例化:

# ...

for player_values in chunks(lines, 4):
    pprint(Player(
        player_values[0],
        player_values[1],
        player_values[2],
        int(player_values[3]),
    ))

# Player(name='George', result='lost', difficulty='H', score=18)
# Player(name='Holly', result='lost', difficulty='H', score=28)
# Player(name='Marcus', result='won', difficulty='H', score=30)

因为您使用的是while str(f.readline) != '':,所以它读取第一行。所以,第一行(以及扩展记录之间的所有行)必须有空行。另外,你的while中的readline缺少副命题()。除此之外,代码是在python3中工作的。您可以使用with打开文件:

with open('test.txt', 'r') as f:
    while True:
        player = Player(f.readline(), f.readline(), f.readline(), f.readline())
        if "" in player:
            break;
        Playerlist.append(player)

for i in range(len(Playerlist)):
    print (Playerlist[i])

它会自动关闭文件并为您处理详细信息。但是,使用json或其他格式是更好的选择。你知道吗

相关问题 更多 >