我有一个巨大的文本文件(1 GB),其中每个“行”都是根据语法:
[number] [number]_[number]
例如:
123 123_1234
45 456_45 12 12_12
我收到以下错误:
line 46, in open_delimited
pieces = re.findall(r"(\d+)\s+(\d+_\d+)", remainder + chunk, re.IGNORECASE)
TypeError: can only concatenate tuple (not "str") to tuple
关于此代码:
def open_delimited(filename, args):
with open(filename, args, encoding="UTF-16") as infile:
chunksize = 10000
remainder = ''
for chunk in iter(lambda: infile.read(chunksize), ''):
pieces = re.findall(r"(\d+)\s+(\d+_\d+)", remainder + chunk, re.IGNORECASE)
for piece in pieces[:-1]:
yield piece
remainder = pieces[-1]
if remainder:
yield remainder
filename = 'data/AllData_2000001_3000000.txt'
for chunk in open_delimited(filename, 'r'):
print(chunk)
答案 0 :(得分:4)
re.findall()
会返回一系列元组。您的模式有两个这样的组。因此,每个piece
由(number, number_number)
对组成:
>>> re.findall(r"(\d+)\s+(\d+_\d+)", '45 456_45 12 12_12')
[('45', '456_45'), ('12', '12_12')]
请注意,由于您只匹配空白和数字 ,因此re.IGNORECASE
标志完全是多余的。
您将最后一个piece
分配给remainder
,然后循环备份并将其添加到chunk
,但这不起作用:
>>> ('12', '12_12') + '123 123_1234\n'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate tuple (not "str") to tuple
也许您想再次将值重新加入有效的文本中:
remainder = '{} {} '.format(*pieces[-1])
答案 1 :(得分:1)
如前所述,处理过程中存在错误:findall()
提供了元组列表。
可以采用替代方法
def open_delimited(filename, args):
with open(filename, args, encoding="UTF-16") as infile:
chunksize = 10000
remainder = ''
for chunk in iter(lambda: infile.read(chunksize), ''):
remainder += chunk # add it to the to-be-processed string
pieces = list(re.finditer(r"(\d+)\s+(\d+_\d+)", remainder, re.IGNORECASE))
# Those pieces are match objects.
for piece in pieces[:-1]: # omit the last one, as before
yield piece.group() # the whole match
remainder = remainder[pieces[-1].start()] # the last one tells us where to start again.
if remainder:
yield remainder
这里,pieces
不是字符串的元组,但它们是匹配对象。他们并没有告诉我们他们包含什么,以及他们来自哪里。
这样可以轻松“重新创建”“余数”。