如何循环直到从文件中读取所有行?
How to loop until all lines read from a file?
我正在尝试建立一个分数系统,我需要将文本文件中的所有分数输入到 'array of records'。
我是 Python
的新手,希望有一个简单的解决方案。
在我的程序中,记录数组在技术上会 class 作为 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')
由于您使用的是 while str(f.readline) != '':
,因此它会读取第一行。因此,第一行(以及记录之间的所有行)必须有空行。此外,您的 while
中的 readline
缺少括号 ()
。除此之外,代码在 python 中运行 3. 您可以使用 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 或其他格式是更好的选择。
这段代码和这种方法都存在一些问题。有很多文件格式对这类事情很有用;一种非常流行的内置 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
class 与简单的自定义序列化程序一起使用, subclass 由 namedtuple
生成的 class 定义了 return 的方法 JSON 或 JSON 可格式化的字典(相当复杂),或者编写一个单独的函数,将您的 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
元组用 player_values
实例化,一个由 chunks
生成并使用 *
扩展的列表。这意味着,不是将列表 player_values
传递给函数 Player.__init__(...)
,而是将单个值作为 *args
发送。如此有效,方法调用变成了 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)
我正在尝试建立一个分数系统,我需要将文本文件中的所有分数输入到 'array of records'。
我是 Python
的新手,希望有一个简单的解决方案。
在我的程序中,记录数组在技术上会 class 作为 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')
由于您使用的是 while str(f.readline) != '':
,因此它会读取第一行。因此,第一行(以及记录之间的所有行)必须有空行。此外,您的 while
中的 readline
缺少括号 ()
。除此之外,代码在 python 中运行 3. 您可以使用 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 或其他格式是更好的选择。
这段代码和这种方法都存在一些问题。有很多文件格式对这类事情很有用;一种非常流行的内置 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
class 与简单的自定义序列化程序一起使用, subclass 由 namedtuple
生成的 class 定义了 return 的方法 JSON 或 JSON 可格式化的字典(相当复杂),或者编写一个单独的函数,将您的 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
元组用 player_values
实例化,一个由 chunks
生成并使用 *
扩展的列表。这意味着,不是将列表 player_values
传递给函数 Player.__init__(...)
,而是将单个值作为 *args
发送。如此有效,方法调用变成了 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)