Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/rest/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将默认值添加到有序dict列表_Python_Python 3.x - Fatal编程技术网

Python 将默认值添加到有序dict列表

Python 将默认值添加到有序dict列表,python,python-3.x,Python,Python 3.x,python 3.8 给定一个OrderedDicts列表,为列表中所有OrderedLists中缺少的所有键设置默认值。必须这样做才能保留订单。 示例 def add_defaults(list_of_dicts, default_value): #implementation goes here pass first = OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')]) second = OrderedDict(

python 3.8

给定一个
OrderedDict
s列表,为列表中所有
OrderedList
s中缺少的所有键设置默认值。必须这样做才能保留订单。

示例

def add_defaults(list_of_dicts, default_value):
    #implementation goes here
    pass

first = OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')])
second = OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k4', 'v4')])
third = OrderedDict([('k2', 'v2'), ('k5', 'v5'), ('k6', 'v6')])
lst=[first, second, third]
print(add_defaults(lst, ''))
预期输出(稍微格式化以简化阅读):

我的实施

def add_defaults(ordered_dict, default_value):
    all_defaults=OrderedDict({}).fromkeys(
            reduce(lambda k, v: OrderedDict(list(k.items()) + list(v.items())), ordered_dict, {}),
            default_value
    )

    results = [OrderedDict(all_defaults) for _ in range(len(ordered_dict))]

    for result, value in zip(results, ordered_dict):
        result.update(value)

    return results
问题


对于这样一个简单的任务,实现看起来过于复杂,不像是最简单的pythonic解决方案。实现它的惯用方法是什么?

首先查看所有的dict似乎是不可避免的,因为您需要知道要包含哪些键。只需将键按所示顺序传递到
OrderedDict()
,就可以更简单地执行此操作:

default = OrderedDict((k, val) for d in l for k in d.keys())
使用此选项,您可以混合列表中的词典:

def add_defaults(l, val):
    default = OrderedDict((k, val) for d in l for k in d.keys())
    return [OrderedDict({**default, **d}) for d in l]

first = OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')])
second = OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k4', 'v4')])
third = OrderedDict([('k2', 'v2'), ('k5', 'v5'), ('k6', 'v6')])

lst=[first, second, third]

print(add_defaults(lst, ''))
印刷品:

[
 OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3'), ('k4', ''), ('k5', ''), ('k6', '')]), 
 OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', ''), ('k4', 'v4'), ('k5', ''), ('k6', '')]), 
 OrderedDict([('k1', ''), ('k2', 'v2'), ('k3', ''), ('k4', ''), ('k5', 'v5'), ('k6', 'v6')])
]

看起来没有办法不先看一遍所有的字典,因为你需要知道应该包括哪些键。只需将键按所示顺序传递到
OrderedDict()
,就可以更简单地执行此操作:

default = OrderedDict((k, val) for d in l for k in d.keys())
使用此选项,您可以混合列表中的词典:

def add_defaults(l, val):
    default = OrderedDict((k, val) for d in l for k in d.keys())
    return [OrderedDict({**default, **d}) for d in l]

first = OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')])
second = OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k4', 'v4')])
third = OrderedDict([('k2', 'v2'), ('k5', 'v5'), ('k6', 'v6')])

lst=[first, second, third]

print(add_defaults(lst, ''))
印刷品:

[
 OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3'), ('k4', ''), ('k5', ''), ('k6', '')]), 
 OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', ''), ('k4', 'v4'), ('k5', ''), ('k6', '')]), 
 OrderedDict([('k1', ''), ('k2', 'v2'), ('k3', ''), ('k4', ''), ('k5', 'v5'), ('k6', 'v6')])
]

是的,这太复杂了。我只需通过一次就可以拿到钥匙:

allkeys = [k for dct in lst for k in dct]
然后,要创建新的有序dict,您需要在键上迭代,并使用默认值
。get

result = [
    OrderedDict( {k: dct.get(k, '') for k in allkeys } )
    for dct in lst
]
所以,一些一般性的建议,要么接受,要么放弃:


您只需使用
OrderedDict.fromkeys(…


在构建新的数据结构时,避免使用
reduce
。Python的内置类型并不是为您在Scala中可能遇到的那种函数式方法而设计的,在Scala中,语言就是基于这一点构建的(例如,列表的实现)。您在这里引入了次优行为,使用串联作为缩减操作,因为这将导致类似多项式时间的结果。它也非常冗长,迫使您创建中间列表

 OrderedDict(list(k.items()) + list(v.items()))

说到上面的lambda,不要随意使用python习语,因此
k,v
应该指字典键值对,或者类似的东西。这里有两个字典,reduce累加器和传入dict。甚至类似于:

lambda acc, d: OrderedDict(list(acc.items()) + list(d.items()))

为读者提供更好的信息。

是的,这太复杂了。我只需做一次简单的操作就可以拿到钥匙:

allkeys = [k for dct in lst for k in dct]
然后,要创建新的有序dict,您需要在键上迭代,并使用默认值
。get

result = [
    OrderedDict( {k: dct.get(k, '') for k in allkeys } )
    for dct in lst
]
所以,一些一般性的建议,要么接受,要么放弃:


您只需使用
OrderedDict.fromkeys(…


在构建新的数据结构时,避免使用
reduce
。Python的内置类型并不是为您在Scala中可能遇到的那种函数式方法而设计的,在Scala中,语言就是基于这一点构建的(例如,列表的实现)。您在这里引入了次优行为,使用串联作为缩减操作,因为这将导致类似多项式时间的结果。它也非常冗长,迫使您创建中间列表

 OrderedDict(list(k.items()) + list(v.items()))

说到上面的lambda,不要随意使用python习语,因此
k,v
应该指字典键值对,或者类似的东西。这里有两个字典,reduce累加器和传入dict。甚至类似于:

lambda acc, d: OrderedDict(list(acc.items()) + list(d.items()))

为读者提供更好的提示。

dict
对象还保留其键的添加顺序。利用此功能,可获得初始键列表:

>>> keys = {**first, **second, **third}.keys()
>>> # or
>>> key_d = {}
>>> for d in (first, second, third):
>>>     key_d.update(d)
>>> keys = key_d.keys()
有趣的是,我们用这种方法得到了有序集合的效果。使用
dict
并添加键作为具有虚拟值的集合项,然后当您想知道集合中的内容时,只需抓取键。它们将按照添加的顺序

使用
dict.keys()
获得的对象本身设置为like,并支持一些set操作;但是,您失去了这些操作的顺序,因此
首先。keys()|第二。keys()|第三。keys()
将为我们提供键的并集,但不是按照表达式中从左到右遇到的顺序。但是,
{**first,**second,**third}.keys()
给出了这个“有序集”按顺序的并集-相同的效果(但按顺序),不同的语法

一旦我们有了这些键,
OrderedDict
s和默认值就很容易创建了

>>> new_first = OrderedDict((k, first.get(k, '')) for k in keys)
>>> new_first
OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3'), ('k4', ''), 
             ('k5', ''), ('k6', '')])
从其他示例来看,使用默认字典生成具有默认值的新字典是一个好主意。此默认字典实际上不必是
OrderedDict
本身

>>> default = {k: '' for d in d_list for k in d.keys()}
>>> new_first = {**default, **first}
new\u first
现在具有给定顺序中的所有键,其中缺少
first
的键具有默认值。
new\u first
已经是一个“有序字典”,但如果我们必须将其专门转换为
OrderedDict

>>> new_first = OrderedDict(new_first)

dict
对象还保留其键的添加顺序。利用此功能,获取初始键列表:

>>> keys = {**first, **second, **third}.keys()
>>> # or
>>> key_d = {}
>>> for d in (first, second, third):
>>>     key_d.update(d)
>>> keys = key_d.keys()
有趣的是,我们用这种方法得到了有序集合的效果。使用
dict
并添加键作为具有虚拟值的集合项,然后当您想知道集合中的内容时,只需抓取键。它们将按照添加的顺序

使用
dict.keys()
获得的对象本身设置为like,并支持一些set操作;但是,您失去了这些操作的顺序,因此
首先。keys()|第二。keys()|第三。keys()
将为我们提供键的并集,但不是按照表达式中从左到右遇到的顺序。但是,
{**first,**second,**third}.keys()
给出了这个“有序集”按顺序的并集-相同的效果(但按顺序),不同的语法

一旦我们有了这些键,
OrderedDict
s和默认值就很容易创建了

>>> new_first = OrderedDict((k, first.get(k, '')) for k in keys)
>>> new_first
OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3'), ('k4', ''), 
             ('k5', ''), ('k6', '')])
从t