如何从 python 中的任意行开始使用 read next()?
How to use read next() starting from any line in python?
我正在尝试从第 3 行开始读取某些文件,但我不能。
我尝试使用 readlines()
+ 行的索引号,如下所示:
x = 2
f = open('urls.txt', "r+").readlines( )[x]
line = next(f)
print(line)
但我得到了这个结果:
Traceback (most recent call last):
File "test.py", line 441, in <module>
line = next(f)
TypeError: 'str' object is not an iterator
我希望能够将任何行设置为变量,并且从那里开始,我一直使用 next()
它会转到下一行。
重要提示:由于这是一项新功能,我的所有代码都已使用 next(f)
,解决方案需要能够使用它。
readlines
方法 returns 行的字符串列表。因此,当您使用 readlines()[2]
时,您将获得第三行,作为一个字符串。在那个字符串上调用 next
就没有意义了,所以你会得到一个错误。
最简单的方法是切片列表:readlines()[x:]
给出了从第x
行开始的所有内容的列表。然后您可以随意使用该列表。
如果您对迭代器情有独钟,则可以使用 iter
内置函数将列表(或几乎任何东西)转换为迭代器。然后你就可以next
尽情享受了。
试试这个(使用 itertools.islice
):
from itertools import islice
f = open('urls.txt', 'r+')
start_at = 3
file_iterator = islice(f, start_at - 1, None)
# to demonstrate
while True:
try:
print(next(file_iterator), end='')
except StopIteration:
print('End of file!')
break
f.close()
urls.txt
:
1
2
3
4
5
输出:
3
4
5
End of file!
此解决方案优于 readlines
,因为它不会将整个文件加载到内存中,只在需要时加载部分文件。当 islice
可以做到这一点时,它也不会浪费时间迭代前几行,这使得它比@MadPhysicist 的答案快得多。
此外,考虑使用 with
语法来保证文件被关闭:
with open('urls.txt', 'r+') as f:
# do whatever
您打印的行 return 是一个字符串:
open('urls.txt', "r+").readlines()[x]
open
returns 一个文件对象。它的 readlines
方法 return 是一个字符串列表。使用 [x]
return 将文件中的第三行作为单个字符串进行索引。
第一个问题是您打开文件但没有关闭它。第二个是您的索引直到最后才指定行范围。这是一个渐进的改进:
with open('urls.txt', 'r+') as f:
lines = f.readlines()[x:]
现在 lines
是您想要的所有行的列表。但是您首先将整个文件读入内存,然后丢弃前两行。此外,列表是可迭代的,而不是迭代器,因此要有效地在其上使用 next
,您需要采取额外的步骤:
lines = iter(lines)
如果您想利用该文件已经是一个相当高效的迭代器这一事实,请根据需要多次对其应用 next
以丢弃不需要的行:
with open('urls.txt', 'r+') as f:
for _ in range(x):
next(f)
# now use the file
print(next(f))
在for
循环之后,任何对文件的读操作都会从第三行开始,无论是next(f)
、f.readline()
等
还有一些其他方法可以去除第一行。在所有情况下,包括上面的示例,next(f)
都可以替换为 f.readline()
:
for n, _ in enumerate(f):
if n == x:
break
或
for _ in zip(f, range(x)): pass
在你 运行 这些循环中的任何一个之后,next(f)
将 return 第 x
行。
以下代码将允许您使用迭代器打印第一行:
In [1]: path = '<path to text file>'
In [2]: f = open(path, "r+")
In [3]: line = next(f)
In [4]: print(line)
此代码将允许您打印从第 x 行开始的行:
In [1]: path = '<path to text file>'
In [2]: x = 2
In [3]: f = iter(open(path, "r+").readlines()[x:])
In [4]: f = iter(f)
In [5]: line = next(f)
In [6]: print(line)
编辑:根据@Tomothy32 的观察编辑了解决方案。
只要需要多次调用 next(f)
即可。 (没有必要用 itertools
使它过于复杂,也没有必要用 readlines
吞噬整个文件。)
lines_to_skip = 3
with open('urls.txt') as f:
for _ in range(lines_to_skip):
next(f)
for line in f:
print(line.strip())
输出:
% cat urls.txt
url1
url2
url3
url4
url5
% python3 test.py
url4
url5
我正在尝试从第 3 行开始读取某些文件,但我不能。
我尝试使用 readlines()
+ 行的索引号,如下所示:
x = 2
f = open('urls.txt', "r+").readlines( )[x]
line = next(f)
print(line)
但我得到了这个结果:
Traceback (most recent call last):
File "test.py", line 441, in <module>
line = next(f)
TypeError: 'str' object is not an iterator
我希望能够将任何行设置为变量,并且从那里开始,我一直使用 next()
它会转到下一行。
重要提示:由于这是一项新功能,我的所有代码都已使用 next(f)
,解决方案需要能够使用它。
readlines
方法 returns 行的字符串列表。因此,当您使用 readlines()[2]
时,您将获得第三行,作为一个字符串。在那个字符串上调用 next
就没有意义了,所以你会得到一个错误。
最简单的方法是切片列表:readlines()[x:]
给出了从第x
行开始的所有内容的列表。然后您可以随意使用该列表。
如果您对迭代器情有独钟,则可以使用 iter
内置函数将列表(或几乎任何东西)转换为迭代器。然后你就可以next
尽情享受了。
试试这个(使用 itertools.islice
):
from itertools import islice
f = open('urls.txt', 'r+')
start_at = 3
file_iterator = islice(f, start_at - 1, None)
# to demonstrate
while True:
try:
print(next(file_iterator), end='')
except StopIteration:
print('End of file!')
break
f.close()
urls.txt
:
1
2
3
4
5
输出:
3
4
5
End of file!
此解决方案优于 readlines
,因为它不会将整个文件加载到内存中,只在需要时加载部分文件。当 islice
可以做到这一点时,它也不会浪费时间迭代前几行,这使得它比@MadPhysicist 的答案快得多。
此外,考虑使用 with
语法来保证文件被关闭:
with open('urls.txt', 'r+') as f:
# do whatever
您打印的行 return 是一个字符串:
open('urls.txt', "r+").readlines()[x]
open
returns 一个文件对象。它的 readlines
方法 return 是一个字符串列表。使用 [x]
return 将文件中的第三行作为单个字符串进行索引。
第一个问题是您打开文件但没有关闭它。第二个是您的索引直到最后才指定行范围。这是一个渐进的改进:
with open('urls.txt', 'r+') as f:
lines = f.readlines()[x:]
现在 lines
是您想要的所有行的列表。但是您首先将整个文件读入内存,然后丢弃前两行。此外,列表是可迭代的,而不是迭代器,因此要有效地在其上使用 next
,您需要采取额外的步骤:
lines = iter(lines)
如果您想利用该文件已经是一个相当高效的迭代器这一事实,请根据需要多次对其应用 next
以丢弃不需要的行:
with open('urls.txt', 'r+') as f:
for _ in range(x):
next(f)
# now use the file
print(next(f))
在for
循环之后,任何对文件的读操作都会从第三行开始,无论是next(f)
、f.readline()
等
还有一些其他方法可以去除第一行。在所有情况下,包括上面的示例,next(f)
都可以替换为 f.readline()
:
for n, _ in enumerate(f):
if n == x:
break
或
for _ in zip(f, range(x)): pass
在你 运行 这些循环中的任何一个之后,next(f)
将 return 第 x
行。
以下代码将允许您使用迭代器打印第一行:
In [1]: path = '<path to text file>'
In [2]: f = open(path, "r+")
In [3]: line = next(f)
In [4]: print(line)
此代码将允许您打印从第 x 行开始的行:
In [1]: path = '<path to text file>'
In [2]: x = 2
In [3]: f = iter(open(path, "r+").readlines()[x:])
In [4]: f = iter(f)
In [5]: line = next(f)
In [6]: print(line)
编辑:根据@Tomothy32 的观察编辑了解决方案。
只要需要多次调用 next(f)
即可。 (没有必要用 itertools
使它过于复杂,也没有必要用 readlines
吞噬整个文件。)
lines_to_skip = 3
with open('urls.txt') as f:
for _ in range(lines_to_skip):
next(f)
for line in f:
print(line.strip())
输出:
% cat urls.txt
url1
url2
url3
url4
url5
% python3 test.py
url4
url5