读取两个单词之间的文件行
reading lines of a file between two words
我有一个包含数字和 2 个单词的文件:"start" 和 "middle"
我想读取一个数组中从 "start" 到 "middle" 的数字,以及从 "middle" 到文件末尾的数字到另一个数组。
这是我的 python 代码:
with open("../MyList","r") as f:
for x in f.readlines():
if x == "start\n":
continue
if x == "middle\n":
break
x = x.split("\n")[0]
list_1.append(int(x))
print list_1
for x in f.readlines():
if x == "middle\n":
continue
list_2.append(int(x))
print list_2
但问题是我的程序从来没有进入第二个循环并跳转到
print list_2
我在较旧的问题中进行了搜索,但无法找出问题所在。
你的第一个循环是读取整个文件直到最后,但只处理了一半。当第二个循环命中时,文件指针已经在末尾,因此没有读取新行。
来自 python 文档:
file.readlines([sizehint])
Read until EOF using readline() and return a list containing the lines
thus read. If the optional sizehint argument is present, instead of
reading up to EOF, whole lines totalling approximately sizehint bytes
(possibly after rounding up to an internal buffer size) are read.
Objects implementing a file-like interface may choose to ignore
sizehint if it cannot be implemented, or cannot be implemented
efficiently.
要么在一个循环中处理所有内容,要么逐行读取(使用 readline
而不是 readlines
)。
这是因为你在第一个循环中读取了整个文件,当它进入第二个循环时,文件指针已经在文件末尾,你将从 f.readlines() 得到一个空列表。
您可以通过重新打开文件或在第二个 for 循环
之前使用 f.seek(0)
将文件指针再次设置为文件开头来解决此问题
with open("../MyList","r") as f:
with open("../MyList","r") as f:
for x in f.readlines():
# process your stuff for 1st loop
# reset file pointer to beginning of file again
f.seek(0)
for x in f.readlines():
# process your stuff for 2nd loop
如果处理大文件,将整个文件读入内存效率不高,你可以只遍历文件对象,而不是像下面的代码那样将所有文件读入内存
list1 = []
list2 = []
list1_start = False
list2_start = False
with open("../MyList","r") as f:
for x in f:
if x.strip() == 'start':
list1_start = True
continue
elif x.strip() == 'middle':
list2_start = True
list1_start = False
continue
if list1_start:
list1.append(x.strip())
elif list2_start:
list2.append(x.strip())
print(list1)
print(list2)
您可以在列表中读取整个文件一次,然后您可以对其进行切片。
如果可能你可以试试这个:
with open("sample.txt","r") as f:
list_1 = []
list_2 = []
fulllist = []
for x in f.readlines():
x = x.split("\n")[0]
fulllist.append(x)
print fulllist
start_position = fulllist.index('start')
middle_position = fulllist.index('middle')
end_position = fulllist.index('end')
list_1 = fulllist[start_position+1 :middle_position]
list_2 = fulllist[middle_position+1 :end_position]
print "list1 : ",list_1
print "list2 : ",list_2
讨论
你的问题是你一次读取了整个文件,当你
开始第二个循环没有什么可读的...
一个可能的解决方案包括逐行读取文件,跟踪
start
和 middle
关键字并更新两个列表之一
因此。
这意味着您的脚本在循环期间必须维护关于
它的当前状态,为此我们将使用
变量,code
,即 0
、1
或 2
,表示无操作,
附加到清单编号1 或附加到清单编号。 2、因为一开始
我们不想做任何事情,它的初始值必须是 0
code = 0
如果我们想使用 code
的值访问两个列表之一
一个开关,我们可以编写一个测试,或者代替测试,我们可以使用
列表列表,lists
,包含一个虚拟列表和两个列表
用有效数字更新。最初所有这些内部列表都是相等的
到空列表 []
l1, l2 = [], []
lists = [[], l1, l2]
以便后面我们可以进行如下操作
lists[code].append(number)
有了这些前提,就很容易把循环体写在
文件行,
- 读一个数
- 如果不是数字,看是不是关键字
- 如果是关键字,改变状态
- 无论如何,不做进一步处理
如果我们必须追加,追加到正确的列表
try:
n = int(line)
except ValueError:
if line == 'start\n' : code=1
if line == 'middle\n': code=2
continue
if code: lists[code].append(n)
我们只需添加一些样板文件,打开文件并
循环,仅此而已。
下面你可以看到我的测试数据,完整的源代码,所有的
脚本的详细信息和测试执行。
演示
$ cat start_middle.dat
1
2
3
start
5
6
7
middle
9
10
$ cat start_middle.py
l1, l2 = [], []
code, lists = 0, [[], l1, l2]
with open('start_middle.dat') as infile:
for line in infile.readlines():
try:
n = int(line)
except ValueError:
if line == 'start\n' : code=1
if line == 'middle\n': code=2
continue
if code: lists[code].append(n)
print(l1)
print(l2)
$ python start_middle.py
[5, 6, 7]
[9, 10]
$
我有一个包含数字和 2 个单词的文件:"start" 和 "middle" 我想读取一个数组中从 "start" 到 "middle" 的数字,以及从 "middle" 到文件末尾的数字到另一个数组。 这是我的 python 代码:
with open("../MyList","r") as f:
for x in f.readlines():
if x == "start\n":
continue
if x == "middle\n":
break
x = x.split("\n")[0]
list_1.append(int(x))
print list_1
for x in f.readlines():
if x == "middle\n":
continue
list_2.append(int(x))
print list_2
但问题是我的程序从来没有进入第二个循环并跳转到
print list_2
我在较旧的问题中进行了搜索,但无法找出问题所在。
你的第一个循环是读取整个文件直到最后,但只处理了一半。当第二个循环命中时,文件指针已经在末尾,因此没有读取新行。
来自 python 文档:
file.readlines([sizehint])
Read until EOF using readline() and return a list containing the lines thus read. If the optional sizehint argument is present, instead of reading up to EOF, whole lines totalling approximately sizehint bytes (possibly after rounding up to an internal buffer size) are read. Objects implementing a file-like interface may choose to ignore sizehint if it cannot be implemented, or cannot be implemented efficiently.
要么在一个循环中处理所有内容,要么逐行读取(使用 readline
而不是 readlines
)。
这是因为你在第一个循环中读取了整个文件,当它进入第二个循环时,文件指针已经在文件末尾,你将从 f.readlines() 得到一个空列表。
您可以通过重新打开文件或在第二个 for 循环
之前使用f.seek(0)
将文件指针再次设置为文件开头来解决此问题
with open("../MyList","r") as f:
with open("../MyList","r") as f:
for x in f.readlines():
# process your stuff for 1st loop
# reset file pointer to beginning of file again
f.seek(0)
for x in f.readlines():
# process your stuff for 2nd loop
如果处理大文件,将整个文件读入内存效率不高,你可以只遍历文件对象,而不是像下面的代码那样将所有文件读入内存
list1 = []
list2 = []
list1_start = False
list2_start = False
with open("../MyList","r") as f:
for x in f:
if x.strip() == 'start':
list1_start = True
continue
elif x.strip() == 'middle':
list2_start = True
list1_start = False
continue
if list1_start:
list1.append(x.strip())
elif list2_start:
list2.append(x.strip())
print(list1)
print(list2)
您可以在列表中读取整个文件一次,然后您可以对其进行切片。
如果可能你可以试试这个:
with open("sample.txt","r") as f:
list_1 = []
list_2 = []
fulllist = []
for x in f.readlines():
x = x.split("\n")[0]
fulllist.append(x)
print fulllist
start_position = fulllist.index('start')
middle_position = fulllist.index('middle')
end_position = fulllist.index('end')
list_1 = fulllist[start_position+1 :middle_position]
list_2 = fulllist[middle_position+1 :end_position]
print "list1 : ",list_1
print "list2 : ",list_2
讨论
你的问题是你一次读取了整个文件,当你 开始第二个循环没有什么可读的...
一个可能的解决方案包括逐行读取文件,跟踪
start
和 middle
关键字并更新两个列表之一
因此。
这意味着您的脚本在循环期间必须维护关于
它的当前状态,为此我们将使用
变量,code
,即 0
、1
或 2
,表示无操作,
附加到清单编号1 或附加到清单编号。 2、因为一开始
我们不想做任何事情,它的初始值必须是 0
code = 0
如果我们想使用 code
的值访问两个列表之一
一个开关,我们可以编写一个测试,或者代替测试,我们可以使用
列表列表,lists
,包含一个虚拟列表和两个列表
用有效数字更新。最初所有这些内部列表都是相等的
到空列表 []
l1, l2 = [], []
lists = [[], l1, l2]
以便后面我们可以进行如下操作
lists[code].append(number)
有了这些前提,就很容易把循环体写在 文件行,
- 读一个数
- 如果不是数字,看是不是关键字
- 如果是关键字,改变状态
- 无论如何,不做进一步处理
如果我们必须追加,追加到正确的列表
try: n = int(line) except ValueError: if line == 'start\n' : code=1 if line == 'middle\n': code=2 continue if code: lists[code].append(n)
我们只需添加一些样板文件,打开文件并 循环,仅此而已。
下面你可以看到我的测试数据,完整的源代码,所有的 脚本的详细信息和测试执行。
演示
$ cat start_middle.dat
1
2
3
start
5
6
7
middle
9
10
$ cat start_middle.py
l1, l2 = [], []
code, lists = 0, [[], l1, l2]
with open('start_middle.dat') as infile:
for line in infile.readlines():
try:
n = int(line)
except ValueError:
if line == 'start\n' : code=1
if line == 'middle\n': code=2
continue
if code: lists[code].append(n)
print(l1)
print(l2)
$ python start_middle.py
[5, 6, 7]
[9, 10]
$