特定列表格式Python

时间:2018-04-25 08:15:54

标签: python

我研究了很多类似的问题,但我似乎无法找到解决方案或我自己。我想要实现的是每个都有两个这种形式的词典:

{'apple': ['5', '65'], 'blue': ['9', '10', '15', '43'],
'is': ['5', '6', '13', '45', '96'], 'yes': ['1', '2', '3', '11'], 
'zone': ['5', '6', '9', '10', '12', '14', '18', '19', '29', '45']}

{'apple': ['43'], 'appricote': ['1', '2', '3', '4', '5', '6'],
'candle': ['1', '2', '4', '5', '6', '9'], 'delta': ['14', '43', '47'], 
'dragon': ['23', '24', '25', '26'], 'eclipse': ['11', '13', '15', '19'], 
'island': ['1', '34', '35']}

我想要遵循以下格式:

apple ['5', '43', '65']
apricot ['1', '2', '3', '4', '5', '6']
blue ['9', '10', '15', '43']
candle ['1', '2', '4', '5', '6', '9']
delta ['14', '43', '47']
dragon ['23', '24', '25', '26']
eclipse ['11', '13', '15', '19']
is ['5', '6', '13', '45', '96']
island ['1', '34', '35']
yes ['1', '2', '3', '11']
zone ['5', '6', '9', '10', '12', '14', '18', '19', '29', '45']

但这是我得到的格式:

apple [['5', '65'], ['43']]
blue [['9', '10', '15', '43']]
is [['5', '6', '13', '45', '96']]
yes [['1', '2', '3', '11']]
zone [['5', '6', '9', '10', '12', '14', '18', '19', '29', '45']]
appricote [['1', '2', '3', '4', '5', '6']]
candle [['1', '2', '4', '5', '6', '9']]
delta [['14', '43', '47']]
dragon [['23', '24', '25', '26']]
eclipse [['11', '13', '15', '19']]
island [['1', '34', '35']]

这是我目前的代码

def merge_dictionaries(dict1, dict2): 
    from itertools import chain
    from collections import defaultdict

    dict3 = defaultdict(list)
    for k, v in chain(dict1.items(), dict2.items()):
        dict3[k].append(v)

    for k, v in dict3.items():
        print(k, v)

所以我的问题是我应该进一步处理我现在的格式还是可以直接实现我想要的格式。 例如,如果你告诉我处理我已经实现的格式,我可以将子列表合并为每个键的一个列表,然后排序,并对键进行排序。但我想知道是否有更直接的方式。

5 个答案:

答案 0 :(得分:3)

您需要使用list.extend而不是list.append

>>> d = defaultdict(list)
>>> for k,v in chain(dict1.items(), dict2.items()):
...     d[k].extend(v)
... 
>>> d
defaultdict(<class 'list'>, {'apple': ['5', '65', '43'], 'blue': ['9', '10', '15', '43'], 'is': ['5', '6', '13', '45', '96'], 'yes': ['1', '2', '3', '11'], 'zone': ['5', '6', '9', '10', '12', '14', '18', '19', '29', '45'], 'appricote': ['1', '2', '3', '4', '5', '6'], 'candle': ['1', '2', '4', '5', '6', '9'], 'delta': ['14', '43', '47'], 'dragon': ['23', '24', '25', '26'], 'eclipse': ['11', '13', '15', '19'], 'island': ['1', '34', '35']})

如果订单很重要,您可以对结果列表进行排序。

答案 1 :(得分:2)

您的代码太复杂了。

a = {'apple': ['5', '65'], 'blue': ['9', '10', '15', '43'],
     'is': ['5', '6', '13', '45', '96'], 'yes': ['1', '2', '3', '11'],
     'zone': ['5', '6', '9', '10', '12', '14', '18', '19', '29', '45']}

b = {'apple': ['43'], 'appricote': ['1', '2', '3', '4', '5', '6'],
     'candle': ['1', '2', '4', '5', '6', '9'], 'delta': ['14', '43', '47'],
     'dragon': ['23', '24', '25', '26'], 'eclipse': ['11', '13', '15', '19'],
     'island': ['1', '34', '35']}

output = []
for key in a:
    temp = a[key]
    if key in b:
        temp.extend(b[key])
    output.append('{} {}'.format(key, sorted(temp)))

print('\n'.join(output))

# is ['13', '45', '5', '6', '96']
# blue ['10', '15', '43', '9']
# zone ['10', '12', '14', '18', '19', '29', '45', '5', '6', '9']
# apple ['43', '5', '65']
# yes ['1', '11', '2', '3']

<强>注意事项:

  • 由于a是一个字典,输出字符串中元素的顺序不是持久的(在Python&lt; = 3.6中)

  • 由于您的值是字符串,因此按字典顺序排序。

如果它们相关,则可以很容易地修复这两点。

答案 2 :(得分:1)

虽然其他答案可能更加pythonic,但在此发布作为替代;另一种解决方案是在打印v

之前展平您的价值print(k, v)

示例,添加以下行:

v = [a for b in v for a in (b if isinstance(b, list) else [b])]

完整代码将是这样的:

dict1 = {'apple': ['5', '65'], 'blue': ['9', '10', '15', '43'],
         'is': ['5', '6', '13', '45', '96'], 'yes': ['1', '2', '3', '11'], 
         'zone': ['5', '6', '9', '10', '12', '14', '18', '19', '29', '45']}

dict2 = {'apple': ['43'], 'appricote': ['1', '2', '3', '4', '5', '6'],
         'candle': ['1', '2', '4', '5', '6', '9'], 'delta': ['14', '43', '47'], 
         'dragon': ['23', '24', '25', '26'], 'eclipse': ['11', '13', '15', '19'], 
         'island': ['1', '34', '35']}


def merge_dictionaries(dict1, dict2): 
    from itertools import chain
    from collections import defaultdict

    dict3 = defaultdict(list)
    for k, v in chain(dict1.items(), dict2.items()):
        dict3[k].append(v)

    for k, v in dict3.items():
        v = [a for b in v for a in (b if isinstance(b, list) else [b])]
        print(k, v)

merge_dictionaries(dict1, dict2)

答案 3 :(得分:1)

只需使用一行即可:

{k: a.get(k,[]) + b.get(k,[]) for k in a.keys() + b.keys()}

答案 4 :(得分:1)

这是一种没有collections的方法。我们的想法是迭代字典键的并集,然后使用默认参数dict.get

d1 = {'apple': ['5', '65'], 'blue': ['9', '10', '15', '43'],
      'is': ['5', '6', '13', '45', '96'], 'yes': ['1', '2', '3', '11'], 
      'zone': ['5', '6', '9', '10', '12', '14', '18', '19', '29', '45']}

d2 = {'apple': ['43'], 'appricote': ['1', '2', '3', '4', '5', '6'],
      'candle': ['1', '2', '4', '5', '6', '9'], 'delta': ['14', '43', '47'], 
      'dragon': ['23', '24', '25', '26'], 'eclipse': ['11', '13', '15', '19'], 
      'island': ['1', '34', '35']}

res = {}

for key in set().union(*(d1, d2)):
    res[key] = sorted(d1.get(key, []) + d2.get(key, []), key=int)

结果:

{'apple': ['5', '43', '65'],
 'appricote': ['1', '2', '3', '4', '5', '6'],
 'blue': ['9', '10', '15', '43'],
 'candle': ['1', '2', '4', '5', '6', '9'],
 'delta': ['14', '43', '47'],
 'dragon': ['23', '24', '25', '26'],
 'eclipse': ['11', '13', '15', '19'],
 'is': ['5', '6', '13', '45', '96'],
 'island': ['1', '34', '35'],
 'yes': ['1', '2', '3', '11'],
 'zone': ['5', '6', '9', '10', '12', '14', '18', '19', '29', '45']}

或通过等效字典理解:

res = {key: sorted(d1.get(key, []) + d2.get(key, []), key=int)
            for key in set().union(*(d1, d2))}

对于有序字典,请在之后使用collections.OrderedDict

from collections import OrderedDict

res = OrderedDict(sorted([(k, v) for k, v in res.items()]))