我想要做的就是创建每行的起始位置列表,这样我就可以非常快速地找到它们.我收到错误,"通过'next()'调用告诉我们禁用位置." 我该如何克服这个问题?
>>> in_file = open("data_10000.txt")
>>> in_file.tell()
0
>>> line_numbers = [in_file.tell() for line in in_file]
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
line_numbers = [in_file.tell() for line in in_file]
File "<pyshell#9>", line 1, in <listcomp>
line_numbers = [in_file.tell() for line in in_file]
OSError: telling position disabled by next() call
Run Code Online (Sandbox Code Playgroud)
注意:在此上下文中,索引会将行号与搜索位置相关联.
一个简单的生成器可以解决您的问题:
\n\ndef line_ind(fileobj):\n i = 0\n for line in fileobj:\n yield i\n i += len(line)\nRun Code Online (Sandbox Code Playgroud)\n\n它会一一产生(生成)行起始位置的索引。您知道常规函数返回一个值并停止。当生成器产生一个值时,它会继续运行直到耗尽。所以我在这里所做的是生成 0,然后将第一行的长度添加到其中,然后生成它,然后添加第二行的长度等。这会生成您想要的索引。
\n\n要将生成的值放入列表中,您可以使用list(generator())与使用相同的方法list(range(10))。当您打开文件时,最好使用with如下所示的方法。不是因为您经常忘记关闭文件对象(您会的),而是它会在发生异常时自动关闭它。因此,通过下面的代码,我有两个起始位置索引列表:
with open("test.dat", encoding="utf-8") as f:\n u_ind = list(line_ind(f))\n f.seek(0)\n u = f.read()\n\nwith open("test.dat", "rb") as f:\n b_ind = list(line_ind(f))\n f.seek(0)\n b = f.read()\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,unicode 字符串的索引可能与字节串的索引不同。例如,重音字符可以占用两个字节的空间。第一个列表包含 unicode 字符的索引。当您处理文件的常规字符串表示形式时,您将使用它。下面的示例显示了测试文件上两种情况下的索引值有何不同:
\n\n>>> u_ind[-10:]\n[24283, 24291, 24300, 24309, 24322, 24331, 24341, 24349, 24359, 24368]\n>>> b_ind[-10:]\n[27297, 27306, 27316, 27326, 27342, 27352, 27363, 27372, 27383, 27393]\nRun Code Online (Sandbox Code Playgroud)\n\n现在我想要最后一行的内容:
\n\n>>> u[24368:]\n\'S-\xc3\xa9rt\xc3\xa9k=9,59\'\n>>> b[27393:]\nb\'S-\\xc3\\xa9rt\\xc3\\xa9k=9,59\'\nRun Code Online (Sandbox Code Playgroud)\n\n但是,如果您想使用seek()before read(),则必须坚持字节索引:
>>> with open("test.dat", encoding="utf-8") as f:\n... f.seek(27393)\n... f.read()\n...\n27393\n\'S-\xc3\xa9rt\xc3\xa9k=9,59\'\n>>> with open("test.dat", "rb") as f:\n... f.seek(27393)\n... f.read()\n...\n27393\nb\'S-\\xc3\\xa9rt\\xc3\\xa9k=9,59\'\nRun Code Online (Sandbox Code Playgroud)\n\n在第一种情况下使用 24368 将是一个可怕的错误。
\n\n请注意,当您将read()文件的内容保存为字符串/字节字符串对象并希望随后处理单独的行时,使用.splitlines().
希望这有帮助!
\n| 归档时间: |
|
| 查看次数: |
1535 次 |
| 最近记录: |