在Python字典中向键添加多个字典

0 投票
3 回答
4413 浏览
提问于 2025-04-18 11:15

我想把多个字典添加到一个键下。

value = { column1 : {entry1 : val1}
                    {entry2 : val2}

          column2 : {entry3 : val3}
                    {entry4 : val4}
}

我用这段代码想做的事情是:有一个文件叫做file.txt,里面有列和每列的有效条目。我想用列名作为键,给每一列再创建一个字典,里面存放每个有效条目。

所以我逐行解析这个文本文件,找出列和条目的模式,并把它们存储到一个变量中。接着检查这个列(也就是键)在字典里是否已经存在,如果存在,就在这个列下添加另一个字典;如果不存在,就创建一个新的条目。我希望这样解释能让你明白。

file.txt的示例内容:

blah blah Column1 blah blah
    entry1 val1
    entry2 val2
blah blah Column2 blah blah
    entry3 val3
    entry4 val4

我的代码:

from __future__ import unicode_literals
import os, re, string, gzip, fnmatch, io
from array import *

header = re.compile(...) #some regex
valid_entries = re.compile(---) #some regex

matches=[]
entries=[]
value = {'MONTH OF INTERVIEW' : {'01': 'MIN VALUE'}}
counter = 0
name = ''

f =open(r'C:/file.txt')

def exists(data, name):
    for key in data.keys():
        if key == name :
            print "existing key : " + name
            return True
        else :
            return False
for line in f:

    col = ''
    ent = ''
    line = re.sub(ur'\u2013', '-', line)
    line = re.sub(ur'\u2026', '_', line)
    m = header.match(line)
    v = valid_entries.match(line)

    if m:
        name= ''
        matches.append(m.groups())
        _,_, name,_,_= m.groups()
        #print "name : " + name

    if v:
        entries.append(v.groups())
        ent,col= v.groups()
        #print v.groups()
        #print "col :" + col
        #print "ent :" + ent

    if (name is not None) and (ent is not None) and (col is not None):
        print value
        if exists(value, name):
            print 'inside existing loop'
            value[name].update({ent:col})
        else:
            value.update({name:{ent:col}})

print value

这段代码的问题是,它替换了子字典的值,而且没有把所有的值都添加到字典里。

我刚学Python,所以这可能是处理这种情况的一种幼稚方法。如果你觉得有更好的方法能实现我想要的效果,我会非常感激你告诉我。

3 个回答

0

你可以使用 defaultdict正则表达式(regex) 来实现这个功能(这里有个示例):

with open('/path/to/file.txt', 'rU') as f:     # read the contents from the file
    lines = f.readlines()

import re
from collections import defaultdict
d = defaultdict(list)                          # dict with default value: []

lastKey = None
for line in lines:
    m = re.search('Column\d',line)             # search the current line for a key
    if m: lastKey = m.group()
    else:
        m = re.search('(?<=entry\d ).*',line)  # search the current line for a value
        if m: d[lastKey].append(m.group())     # append the value

输出结果:

[('Column1', ['val1', 'val2']), ('Column2', ['val3', 'val4'])]

注意:当然,上面的代码是基于你的文件格式和示例来写的。如果你的实际文件数据格式不同,可能需要调整正则表达式。

1

我会把这些键保存成一个字典的列表,这样你就可以用 extendappend 来添加新的内容。

>>> d = {}
>>> d[1] = [{'a': 1}]
>>> d[1].append({'b':2})
>>> d
{1: [{'a': 1}, {'b': 2}]}
2

字典每个键只能对应一个值。这里的窍门是把这个值也做成一个容器,比如说列表:

value = {
    'column1': [{entry1 : val1}, {entry2 : val2}]
    'column2': [{entry3 : val3}, {entry4 : val4}]
}

可以使用 dict.setdefault() 方法,当还没有值的时候插入一个列表作为值:

if name is not None and ent is not None and col is not None:
    value.setdefault(name, []).append({ent: col})

你也可以把值做成一个单一的字典,里面有多个 (ent, col) 的键值对:

if name is not None and ent is not None and col is not None:
    value.setdefault(name, {})[ent] = col

你的 exists() 函数让本来简单的事情变得复杂了;检查一个键是否存在其实可以用 in 来完成:

if name in value:

这样就足够了。

撰写回答