TypeError:只能将元组(不是“str”)连接到元组

时间:2013-08-12 15:03:35

标签: python tuples

我有一个巨大的文本文件(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)   

2 个答案:

答案 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不是字符串的元组,但它们是匹配对象。他们并没有告诉我们他们包含什么,以及他们来自哪里。

这样可以轻松“重新创建”“余数”。