嘿那里,我有一个相当大的文件,我想用Python处理,我对如何做到这一点感到困惑。
我的文件格式如下:
0 xxx xxxx xxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1 xxx xxxx xxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
所以我基本上想要从0-1读取块,对它进行处理,然后转到1和2之间的块。
到目前为止,我已经尝试使用正则表达式匹配数字,然后继续迭代,但我确信必须有更好的方法来解决这个问题。任何建议/信息将不胜感激。
答案 0 :(得分:3)
如果它们都在同一行内,那就是“1”之间没有换行符。和“2.”然后你可以像这样迭代文件的行:
for line in open("myfile.txt"):
#do stuff
该行将在每次迭代时被处理和覆盖,这意味着您可以轻松处理大文件大小。如果他们不在同一条线上:
for line in open("myfile.txt"):
if #regex to match start of new string
parsed_line = line
else:
parsed_line += line
以及其他代码。
答案 1 :(得分:2)
为什么不用char file.read(1)
来读取char文件?
然后,您可以 - 在每次迭代中 - 检查您是否到达了char 1
。然后你必须确保存储字符串很快。
答案 2 :(得分:1)
如果“N”只能开始一行,那么为什么不使用“简单”解决方案呢? (听起来这已经完成了,我正在努力加强/支持它; - ))
即,一次只读一行,并构建表示当前N对象的数据。在说N = 0并且加载N = 1之后,将它们一起处理,然后移动到下一对(N = 2,N = 3)。唯一甚至远程棘手的事情就是确保不要丢弃读取线。 (确定结束条件的读取行 - 例如“N” - 也包含下一个N的数据。
除非需要搜索(或禁用IO缓存或每个项目存在大量数据),否则没有理由不使用readline AFAIK。
快乐的编码。
这是一些袖口代码,可能包含多个错误。无论如何,它使用最小化的副作用方法显示了一般的想法。
# given an input and previous item data, return either
# [item_number, data, next_overflow] if another item is read
# or None if there are no more items
def read_item (inp, overflow):
data = overflow or ""
# this can be replaced with any method to "read the header"
# the regex is just "the easiest". the contract is just:
# given "N ....", return N. given anything else, return None
def get_num(d):
m = re.match(r"(\d+) ", d)
return int(m.groups(1)) if m else None
for line in inp:
if data and get_num(line) ne None:
# already in an item (have data); current line "overflows".
# item number is still at start of current data
return [get_num(data), data, line]
# not in item, or new item not found yet
data += line
# and end of input, with data. only returns above
# if a "new" item was encountered; this covers case of
# no more items (or no items at all)
if data:
return [get_num(data), data, None]
else
return None
用法可能类似于以下内容,其中f
代表一个打开的文件:
# check for error conditions (e.g. None returned)
# note feed-through of "overflow"
num1, data1, overflow = read_item(f, None)
num2, data2, overflow = read_item(f, overflow)
答案 3 :(得分:0)
如果格式是固定的,为什么不用readline()
一次读取3行答案 4 :(得分:0)
如果文件很小,你可以读取整个文件和split()数字数字(可能想用strip()来删除空格和换行符),然后将列表折叠到处理列表中的每个字符串。您可能必须检查您正在处理的结果字符串最初是否为空,以防两个数字彼此相邻。
答案 5 :(得分:0)
如果文件的内容可以加载到内存中,而这就是你的回答,那么下面的代码(需要定义文件名)可能是一个解决方案。
import re
regx = re.compile('^((\d+).*?)(?=^\d|\Z)',re.DOTALL|re.MULTILINE)
with open(filename) as f:
text = f.read()
def treat(inp,regx=regx):
m1 = regx.search(inp)
numb,chunk = m1.group(2,1)
li = [chunk]
for mat in regx.finditer(inp,m1.end()):
n,ch = mat.group(2,1)
if int(n) == int(numb) + 1:
yield ''.join(li)
numb = n
li = []
li.append(ch)
chunk = ch
yield ''.join(li)
for y in treat(text):
print repr(y)
此代码在包含以下内容的文件上运行:
1 mountain
orange 2
apple
produce
2 gas
solemn
enlightment
protectorate
3 grimace
song
4 snow
wheat
51 guludururu
kelemekinonoto
52asabi dabada
5 yellow
6 pink
music
air
7 guitar
blank 8
8 Canada
9 Rimini
产生
'1 mountain\norange 2\napple\nproduce\n'
'2 gas\nsolemn\nenlightment\nprotectorate\n'
'3 grimace\nsong\n'
'4 snow\nwheat\n51 guludururu\nkelemekinonoto\n52asabi dabada\n'
'5 yellow\n'
'6 pink \nmusic\nair\n'
'7 guitar\nblank 8\n'
'8 Canada\n'
'9 Rimini'