压缩多个字典或OrderedDict,以保持顺序并提供默认值(例如zip_longest)

时间:2019-03-14 22:30:07

标签: python python-3.x python-2.7 dictionary

我没有找到我想要的答案,所以我自己找出了答案,并希望与您分享。这些是:Python equivalent of zip for dictionaries既不实现“默认值”(又称最长风味),也不保持顺序。

如何以“ zip_longest”风格在python中压缩OrderedDict

具有:

from collections import OrderedDict

o1 = OrderedDict([("key_a", "a1"), ("key_b", "b1")])
o2 = OrderedDict([("key_a", "a2"), ("key_h", "h2")])
o3 = OrderedDict([("key_c", "c3")])
o4 = OrderedDict([("key_x", "x4")])

如何从传递的每个OrderedDict中获取成对的键值和相应的压缩值,但是如果缺少该值,则使用None

expected_result = [
    ('key_a', ('a1', 'a2', None, None)),
    ('key_b', ('b1', None, None, None)),
    ('key_h', (None, 'h2', None, None)),
    ('key_c', (None, None, 'c3', None)),
    ('key_x', (None, None, None, 'x4')),
]

2 个答案:

答案 0 :(得分:1)

@blhsing提供了最可爱的solution。这是另一种选择。 在python 2和3中工作:

def zip_ordered_mappings_default(*mappings):
    collected_keys = set()
    for key in (key for mapping in mappings for key in mapping):
        if key not in collected_keys:
            collected_keys.add(key)
            yield key, tuple(collection.get(key) for collection in mappings)

# usage:
assert list(zip_ordered_mappings_default(o1, o2, o3, o4)) == expected_result

保留结果项的顺序,并等同于根据传递的dict的键创建的有序集的并集。即新密钥显示在末尾。

该解决方案非常通用,也可以与常规dict一起使用:

assert dict(zip_ordered_mappings_default(dict(o1), dict(o2), dict(o3), dict(o4))) == {
    'key_a': ('a1', 'a2', None, None),
    'key_b': ('b1', None, None, None),
    'key_h': (None, 'h2', None, None),
    'key_c': (None, None, 'c3', None),
    'key_x': (None, None, None, 'x4')
}

当然不会保留dicts项的顺序,但是结果值中的元组会反映函数参数的顺序。

答案 1 :(得分:1)

您可以使用列表推导对从给定字典的所有键创建的<div id="header"></div> <h2 id="page-title">Create Item</h2> <div id="create-customer-form" class="row"> <form id="form" action="/create-item" method="POST" class="col s4 offset-m4"> <div class="row"> <div class="input-field col s12"> <select name="collection" id="myDropdown" class="materialSelect"> <option disabled selected>Choose Season</option> </select> <label>Collection</label> </div> </div> <div class="row"> <div class="input-field col s12"> <input placeholder="Type" name="type" type="text" class="validate"> <label class="label" for="type">Type</label> </div> </div> <div class="row"> <div class="input-field col s12"> <input placeholder="Model" name="model" type="text" class="validate"> <label class="label" for="model">Model</label> </div> </div> <div class="row"> <div class="input-field col s12"> <input placeholder="Color" name="color" type="text" class="validate"> <label class="label" for="color">Color</label> </div> </div> <div class="row"> <div class="input-field col s12"> <input placeholder="Price" name="price" type="number" class="validate"> <label class="label" for="price">Price</label> </div> </div> <div class="row"> <div class="input-field col s12"> <textarea placeholder="Short Description" name="description" type="text" class="materialize-textarea validate"></textarea> <label class="label" for="description">Short Description</label> </div> </div> <div class="row"> <div class="input-field col s12"> <input placeholder="Barcode" name="barcode" type="number" class="validate" data-length="9"> <label class="label" for="barcode">Barcode</label> </div> </div> <div id="submit-btn"> <a id="submit-link" class="waves-effect waves-light btn create-btn"><i class="material-icons left">add</i>create</a> </div> </form> </div> <script src="../main.js"></script> <script src="scripts/jQuery.js" type="text/javascript"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script> <script> $(document).ready(function () { $.ajax({ url: '/collections', }).then(function (options) { $.each(options, function (key, value) { var $newOpt = $("<option>").attr("value", value.name_year).text(value.name_year); $("#myDropdown").append($newOpt); }); $("#myDropdown").trigger('contentChanged'); }); }); $('.materialSelect').formSelect(); $('.materialSelect').on('contentChanged', function () { $(this).formSelect(); }); document.addEventListener('DOMContentLoaded', function () { var elems = document.querySelectorAll('select'); var instances = M.FormSelect.init(elems); }); document.getElementById("submit-link").onclick = function () { document.getElementById("form").submit(); } </script> 进行迭代,并输出键值元组,其值是具有生成器表达式的元组,该表达式遍历字典并返回每个字典中给定键的值:

OrderedDict

使def zip_dicts(*dicts): return [(k, tuple(d.get(k) for d in dicts)) for k in OrderedDict.fromkeys(k for d in dicts for k in d)] 返回:

zip_dicts(o1, o2, o3, o4)