两个文件。一个有损坏的数据,另一个有修复。破损:
ID 0
T5 rat cake
~EOR~
ID 1
T1 wrong segg
T2 wrong nacob
T4 rat tart
~EOR~
ID 3
T5 rat pudding
~EOR~
ID 4
T1 wrong sausag
T2 wrong mspa
T3 strawberry tart
~EOR~
ID 6
T5 with some rat in it
~EOR~
修复:
ID 1
T1 eggs
T2 bacon
~EOR~
ID 4
T1 sausage
T2 spam
T4 bereft of loif
~EOR~
EOR表示记录结束。请注意,断开的文件比修复文件有更多的记录,修复文件有要修复的标记(T1、T2等是标记)和要添加的标记。这段代码正是它应该做的:
# foobar.py
import codecs
source = 'foo.dat'
target = 'bar.dat'
result = 'result.dat'
with codecs.open(source, 'r', 'utf-8_sig') as s, \
codecs.open(target, 'r', 'utf-8_sig') as t, \
codecs.open(result, 'w', 'utf-8_sig') as u:
sID = ST1 = sT2 = sT4 = ''
RecordFound = False
# get source data, record by record
for sline in s:
if sline.startswith('ID '):
sID = sline
if sline.startswith('T1 '):
sT1 = sline
if sline.startswith('T2 '):
sT2 = sline
if sline.startswith('T4 '):
sT4 = sline
if sline.startswith('~EOR~'):
for tline in t:
# copy target file lines, replacing when necesary
if tline == sID:
RecordFound = True
if tline.startswith('T1 ') and RecordFound:
tline = sT1
if tline.startswith('T2 ') and RecordFound:
tline = sT2
if tline.startswith('~EOR~') and RecordFound:
if sT4:
tline = sT4 + tline
RecordFound = False
u.write(tline)
break
u.write(tline)
for tline in t:
u.write(tline)
我正在写一个新文件,因为我不想把另外两个搞砸。第一个外部for循环在fixes文件的最后一条记录上结束。此时,仍有记录要写入目标文件。最后一个for子句就是这样做的。你知道吗
让我烦恼的是,最后一行隐式地拾取了第一个内部for循环最后一次中断的位置。就好像它应该说“为了这条线的其余部分”。另一方面,我不明白如何用更少(或不是更多)的代码行(使用dicts和你所拥有的东西)来实现这一点。我应该担心吗?你知道吗
请评论。你知道吗
我不会担心的。在您的示例中,
t
是一个文件句柄,您正在对其进行迭代。Python中的文件句柄是它们自己的迭代器;它们具有关于在文件中读取位置的状态信息,并且在您对它们进行迭代时将保留它们的位置。您可以查看python文档中的file.next()以获取更多信息。你知道吗另请参阅另一个同样讨论迭代器的SO答案:What does the "yield" keyword do in Python?。有很多有用的信息!你知道吗
编辑:这里有另一种使用字典组合它们的方法。如果要在输出之前对记录进行其他修改,则需要使用此方法:
dict(broken[id].items() + fixed[id].items())
部分利用了这一点: How to merge two Python dictionaries in a single expression?为了完整起见,为了分享我的热情和我学到的东西,下面是我现在使用的代码。它回答了我的问题,还有更多。你知道吗
这部分是基于上述阿卡雷姆的方法。一个函数填充一个dict。它被调用两次,一次用于修复文件,一次用于要修复的文件。你知道吗
它现在是一个有序的dict。这不在我的OP中,但是文件需要由人类交叉检查,所以保持顺序会更容易。(Using OrderedDict is really easy)。我第一次尝试找到这个功能时就想到了odict,但是它的文档让我很担心。没有例子,吓人的行话……)
而且,它现在支持记录中任意给定标记的多次出现。这也不在我的行动中,但我需要这个。(这种格式叫做‘Adlib taged’,是一种编目软件。)
与akaRem的方法不同的是修补,对目标dict使用
update
,我发现这和python一样非常优雅。对于startswith
也是如此。这是我忍不住分享的另外两个原因。你知道吗我希望它有用。你知道吗
有问题吗?你知道吗
相关问题 更多 >
编程相关推荐