繁体   English   中英

解析字典时的python KeyError

[英]python KeyError on parsing a dictionary

如何加入这两个文本文件?

文件1:

1000001 10:0.471669 250:0.127552 30:0.218773 64:0.249413
1000002 130:0.0839656 107:0.185613 30:0.446355 110:0.38011
1000003 1:0.0835855 1117:0.0647112 302:0.0851354 46:0.0601825 48:0.098907 516:0.167713

文件2:

1000001 161:0.115664 207:0.136537 294:0.0974809 301:0.199868
1000002
1000003 555:0.0585849 91:0.0164101

结果:

1000001 10:0.471669 250:0.127552 30:0.218773 64:0.249413 161:0.115664 207:0.136537 294:0.0974809 301:0.199868
1000002 130:0.0839656 107:0.185613 30:0.446355 110:0.38011
1000003 1:0.0835855 1117:0.0647112 302:0.0851354 46:0.0601825 48:0.098907 516:0.167713 555:0.0585849 91:0.0164101

说明:
文档1文档2都具有相同的结构,并且它们具有相同的行数。
每行以一个数字(两个文档中的数字相同)开头,然后每行中有几个项目由数字+冒号+一个十进制数字组成:
例子 10:0.471669
这些项目组合是唯一的,我要做的是将它们合并在一起:从第二个文档的每一行中取出这些项目,并将其放在第一个文档的相应行中。
注意:
开头的初始编号和彼此之间的项目用一个空格分隔。

更新

这是我的尝试:

dat1 = {}
with open('doc1') as f:
    for line in f.readlines():
        dat1[line.split(' ')[0]] = line.strip().split(' ')[1:]

dat2 = {}
with open('doc2') as f:
    for line in f.readlines():
        key = line.split(' ')[0]
        dat2[key] = line.split(' ')[1:]

for key in dat1.keys():
    print("%s %s %s" % (key, str.join(' ', dat1[key]), str.join(' ', dat2[key])))

当该行没有任何内容要添加到第一个文档时,我在第二个文档的行上得到了KeyError的回溯。 在上面的示例中,第二个文档的第二行就是这种情况。
我该如何逃避此异常? 转义仅包含关键字而没有其他要添加的行?

一种更简单的方法可能是使用列表的defaultdict

from collections import defaultdict

data = defaultdict(list)

for filename in 'doc1', 'doc2':
    with open(filename) as f:
        for line in f:
            key, _, value = line.partition(' ')
            data[key.strip()].append(value.strip())

for key in sorted(data):
    print key, ' '.join(data[key])    # Python 2
#    print(key, *data[key])            # Python 3

关于结果的打印,您可以添加:

from __future__ import print_function

到文件顶部,然后Python 2将提供Python 3 print()函数,即,您可以使用上面的Python 3打印。


您在注释中询问了如何打印到文件(导入print_function之后是Python 3还是Python 2):

with open('outfile.txt', 'w') as f:
    for key in sorted(data):
        print(key, *data[key], file=f)

问题在于换行符。

文件中每一行的末尾都有一个换行符,它将包含在每一行的最后一个条目中。 发生异常是因为dat1将具有键"1000002"而dat2将具有键"1000002\\n"

如果在解析之前有line = line.strip() ,则代码应该可以按预期工作。

for line in f.readlines():
    line = line.strip()
    key = line.split(' ')[0]
    dat2[key] = line.split(' ')[1:]

您可以使用pop操作获取数组的第一项,如下所示:

def read_stem(f):
        res = {}
        for line in f.readlines():
                items = line.strip().split()
                res[items.pop(0)] = items
        return res

with open('stem.data') as f:
        dat1 = read_stem(f)

with open('stem.info') as f:
        dat2 = read_stem(f)

with open('myfile','w') as f:
    for key in dat1.keys():
            f.write("%s %s\n" % (key, ' '.join(dat1[key] + dat2[key])))

在第二个文件的代码中,空行的键是'1000002 \\ n'而不是1000002,这可能是原因,这是可行的。

file1_lines= open('doc1', 'r').readlines()
file2_lines = open('doc1', 'r').readlines()
resfile = open('res.txt','w')


dat1 = {}
for line in file1_lines:
    dat1[line.split(' ')[0]] = line.strip().split(' ')[1:]

dat2 = {}
for line in file2_lines:
    dat2[line.strip().split(' ')[0]] = line.strip().split(' ')[1:]

print(dat1)
print(dat2)

for key in dat1.keys():
    print("%s %s %s" % (key, str.join(' ', dat1[key]), str.join(' ', dat2[key])))
    resfile.write("%s %s %s" % (key, str.join(' ', dat1[key]), str.join(' ', dat2[key])))

您可以使用:

doc1_name = 'doc1'
doc2_name = 'doc2'

def get_key_and_value(key_value_list):
    if len(key_value_list) == 2:
        # list has key and values
        key, value = key_value_list
    elif len(key_value_list) == 1:
        # list only has key
        key, value = key_value_list[0], ''
    else:
        # should not happen!
        key, value = '', ''
    return key,value

def join_dict(key, value, _dict, sep=' '):
    if key in _dict.keys():
        _dict[key] = sep.join((_dict[key], value))
    else:
        _dict[key] = value

result = {}
with open(doc1_name, 'r') as doc1, \
     open(doc2_name, 'r') as doc2:
         doc1_lines = doc1.readlines()
         doc2_lines = doc2.readlines()

for list_of_lines in (doc1_lines, doc2_lines):
    for line in list_of_lines:
        # The .strip('\n') removes the \n at the end
        # and the .split(' ', 1) split only once
        key_value = line.strip('\n').split(' ', 1)
        # split the lines only once to get the keys:
        key, value = get_key_and_value(key_value)
        # this can be ignored if it is known that the keys will be the same
        join_dict(key, value, result)

# order the keys
ordered_keys = result.keys()
ordered_keys.sort()
# and write them to a file
with open('+'.join((doc1_name,doc2_name)),'w') as output:
    for key in ordered_keys:
        output.write(' '.join((key, result[key]))+'\n')

doc1

1000001 10:0.471669 250:0.127552 30:0.218773 64:0.249413
1000002 130:0.0839656 107:0.185613 30:0.446355 110:0.38011
1000003 1:0.0835855 1117:0.0647112 302:0.0851354 46:0.0601825 48:0.098907 516:0.167713

doc2

1000001 161:0.115664 207:0.136537 294:0.0974809 301:0.199868
1000002
1000003 555:0.0585849 91:0.0164101

doc1 + doc2

1000001 10:0.471669 250:0.127552 30:0.218773 64:0.249413 161:0.115664 207:0.136537 294:0.0974809 301:0.199868
1000002 130:0.0839656 107:0.185613 30:0.446355 110:0.38011 
1000003 1:0.0835855 1117:0.0647112 302:0.0851354 46:0.0601825 48:0.098907 516:0.167713 555:0.0585849 91:0.0164101

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM