从列表元素形成字典

时间:2015-10-11 08:03:47

标签: python list dictionary split

嗨我有如下列表,其中包含来自图像的元数据,如下所示:

['Component 1: Y component: Quantization table 0, Sampling factors 1 horiz/1 vert', 
 'Component 2: Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert', 
 'Component 3: Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert', 
 'Compression Type: Progressive, Huffman', 'Content-Length: 14312', 'Content-Type: image/jpeg’]

我想使用以下格式拆分列表“:”来制作字典:

{Component 1: {Y component: [Quantization table 0, Sampling factors 1 horiz/1 vert’], 
 Component 2: {Cb component: [Quantization table 1, Sampling factors 1 horiz/1 vert]}, 
 Component 3: {Cr component: [Quantization table 1, Sampling factors 1 horiz/1 vert]}, 
 Compression Type: [Progressive, Huffman],Content-Length: 14312,Content-Type: image/jpeg}

目前我已经编写了一些无效的代码。

def make_dict(seq):
res = {}
if seq[0] is not '':
    for elt in seq:
        k, v = elt.split(':')
        try:
            res[k].append(v)  
        except KeyError:
            res[k] = [v]

print res

此代码不起作用。我也尝试了其他方法,但我无法获得格式。

4 个答案:

答案 0 :(得分:3)

您可以使用collections.OrderedDict

在字典理解中使用列表推导
>>> li=['Component 1: Y component: Quantization table 0, Sampling factors 1 horiz/1 vert', 'Component 2: Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert', 'Component 3: Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert', 'Compression Type: Progressive, Huffman', 'Content-Length: 14312', 'Content-Type: image/jpeg']
>>> d=OrderedDict((sub[0],{sub[1]:sub[2:]}) if sub[2:] else (sub[0],sub[1]) for sub in [item.split(':') for item in li])
>>> d
OrderedDict([('Component 1', {' Y component': [' Quantization table 0, Sampling factors 1 horiz/1 vert']}), ('Component 2', {' Cb component': [' Quantization table 1, Sampling factors 1 horiz/1 vert']}), ('Component 3', {' Cr component': [' Quantization table 1, Sampling factors 1 horiz/1 vert']}), ('Compression Type', ' Progressive, Huffman'), ('Content-Length', ' 14312'), ('Content-Type', ' image/jpeg')])
>>> 

答案 1 :(得分:3)

l = ['Component 1: Y component: Quantization table 0, Sampling factors 1 horiz/1 vert',
     'Component 2: Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert',
     'Component 3: Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert',
     'Compression Type: Progressive, Huffman', 'Content-Length: 14312', 'Content-Type: image/jpeg']

d = {}

for ele in l:
    spl = ele.split(":", 2)
    if len(spl) == 3:
        k1, k2, v = spl
        d[k1] = {k2: v.split(",")}
    else:
        k,v = spl
        d[k] =   v.split() if "," in v  else v

输出:

{'Component 1': {' Y component': [' Quantization table 0',
                                  ' Sampling factors 1 horiz/1 vert']},
 'Component 2': {' Cb component': [' Quantization table 1',
                                   ' Sampling factors 1 horiz/1 vert']},
 'Component 3': {' Cr component': [' Quantization table 1',
                                   ' Sampling factors 1 horiz/1 vert']},
 'Compression Type': [' Progressive', ' Huffman'],
 'Content-Length': ' 14312',
 'Content-Type': ' image/jpeg'}

要删除空格,您可以str.strip关闭它:

d = {}

for ele in l:
    spl = ele.split(":", 2)
    if len(spl) == 3:
        k1, k2, v = spl
        d[k1] = {k2.strip(): list(map(str.strip,v.split(",")))}
    else:
        k,v = spl
        d[k] = list(map(str.strip, v.split())) if "," in v  else v.strip

输出:

{'Component 1': {'Y component': ['Quantization table 0',
                                 'Sampling factors 1 horiz/1 vert']},
 'Component 2': {'Cb component': ['Quantization table 1',
                                  'Sampling factors 1 horiz/1 vert']},
 'Component 3': {'Cr component': ['Quantization table 1',
                                  'Sampling factors 1 horiz/1 vert']},
 'Compression Type': ['Progressive', 'Huffman'],
 'Content-Length': '14312',
 'Content-Type': 'image/jpeg'}

这两者实际上都符合您的预期输出。

答案 2 :(得分:2)

如果要处理任何级别的字典嵌套,可以使用如下所示的递归算法。示例 -

def makedict(elem):
    if ':' in elem:
        k,v = map(str.strip, elem.split(':',1))
        return {k:makedict(v)}
    elif ',' in elem:
        elems = list(map(str.strip, elem.split(','))) #Simply map(...) for Python 2.x
        return elems
    return elem

如果你想制作一本字典词典,你可以这样做 -

d = {}
for elem in s:
    d.update(makedict(elem))

或者,如果你想要一个词典词典列表,请在列表推导中为列表中的每个元素调用上面的函数,例如 -

result = [makedict(elem) for elem in yourlist]

词典词典演示 -

>>> d = {}
>>> for elem in s:
...     d.update(makedict(elem))
...
>>> d
{'Component 2': {'Cb component': ['Quantization table 1', 'Sampling fac
>>> import pprint
>>> pprint.pprint(d)
{'Component 1': {'Y component': ['Quantization table 0',
                                 'Sampling factors 1 horiz/1 vert']},
 'Component 2': {'Cb component': ['Quantization table 1',
                                  'Sampling factors 1 horiz/1 vert']},
 'Component 3': {'Cr component': ['Quantization table 1',
                                  'Sampling factors 1 horiz/1 vert']},
 'Compression Type': ['Progressive', 'Huffman'],
 'Content-Length': '14312',
 'Content-Type': 'image/jpeg'}

答案 3 :(得分:1)

您可以使用递归优雅地解决问题,并且可以使用分割限制(split的第二个参数来限制拆分计数):

def make_dict(l):
    d = dict()
    for elem in l:
        key, value = elem.split(':', 1)
        if ':' in value:
            d[key] = make_dict([value])
        else:
            d[key] = value
    return d

并且测试似乎符合您的期望:

>>> l = ['Component 1: Y component: Quantization table 0, Sampling factors 1 horiz/1 vert',
     'Component 2: Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert',
     'Component 3: Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert',
     'Compression Type: Progressive, Huffman', 'Content-Length: 14312', 'Content-Type: image/jpeg']
>>> make_dict(l)
{'Component 1': {' Y component': ' Quantization table 0, Sampling factors 1 horiz/1 vert'},
 'Component 2': {' Cb component': ' Quantization table 1, Sampling factors 1 horiz/1 vert'},
 'Component 3': {' Cr component': ' Quantization table 1, Sampling factors 1 horiz/1 vert'},
 'Compression Type': ' Progressive, Huffman',
 'Content-Length': ' 14312',
 'Content-Type': ' image/jpeg'}