我需要写一个程序,它有一个名字列表,在每组名字下面(在两行中)是由逗号(1,2)组成的两组数字
所以像这样的
Jane
Doe
14.5,12.3
用同样的3行重复,直到循环到达0,0,结束循环。
如何准确地编写具有同步输入的循环,以及如何区分字符串和数字。
如果条目被分成三行,我将使用:
data = []
with open('inputfile.txt') as inf:
numbers = None
while numbers != [0, 0]:
name1 = next(inf).strip()
name2 = next(inf).strip()
numbers = [float(n) for n in next(inf).split(',')]
data.append((name1, name2, numbers))
这将输入文件用作可迭代对象,每次获取3行,直到numbers
等于[0, 0]
。
我使用takewhile
和使用ast.literal_eval
的自定义函数,以及itertools
的grouper
配方,然后将其转置一点,例如:
from itertools import takewhile, izip_longest
from ast import literal_eval
def until_0(text):
try:
return literal_eval(text) != (0, 0)
except ValueError:
return True
with open('/home/jon/data.txt') as fin:
lines = (line.rstrip() for line in fin)
data = list(takewhile(until_0, lines))
def grouper(n, iterable, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
print [list(el) for el in grouper(3, data, fillvalue='0,0')]
# [['Jane', 'Doe', '14.5,12.3'], ['Jane', 'Doe', '6.7,2.3'], ['John', 'Doe', '0,0']]
有意义的第一步是将你的列表缩减到只剩下你需要的名字和数字。这很容易做到因为你只对列表中第一行'0,0'之前的那部分感兴趣:你可以取那一行的索引,然后对列表进行切片,得到那个section:
your_data = ['Jane', 'Doe', '14.5,12.3', etc etc]
z_index = your_data.index('0,0')
new_data = your_data[:z_index + 1] # +1 to include '0,0' as the last element
从那里它取决于你想对数据做什么。但是假设你想要一个包含名字和数字的字典列表:
results = []
while new_data:
results.append({'first':new_data[0],
'last':new_data[1],
'numbers':new_data[2]})
new_data = new_data[3:]
这里的数字对仍然是字符串,因为它是从你的txt文件中读取的。如果需要,您可以在将数字赋值给字典时拆分数字并将其转换为浮点数。
另外,我在这里做了一些假设:你的列表将始终包含行'0,0',并且它不会丢失任何第一行/最后一行/数字行。如果情况并非总是如此,则需要一些逻辑来处理异常。