使用字典作为可选参数的函数-Python

使用字典作为可选参数的函数-Python,python,dictionary,optional-arguments,Python,Dictionary,Optional Arguments,我正在尝试创建一个函数,它可以接收许多或一些字典作为输入。我正在使用以下代码: def merge_many_dics(dic1,dic2,dic3=True,dic4=True,dic5=True,dic6=True,dic7=True,dic8=True,dic9=True,dic10=True): """ Merging up to 10 dictionaries with same keys and different values :return: a dictionary conta

我正在尝试创建一个函数,它可以接收许多或一些字典作为输入。我正在使用以下代码:

def merge_many_dics(dic1,dic2,dic3=True,dic4=True,dic5=True,dic6=True,dic7=True,dic8=True,dic9=True,dic10=True):
"""
Merging up to 10 dictionaries with same keys and different values
:return: a dictionary containing the common dates as keys and both values as values
"""
manydics = {}
for k in dic1.viewkeys() & dic2.viewkeys() & dic3.viewkeys() & dic4.viewkeys() & dic5.viewkeys() & dic6.viewkeys()\
        & dic7.viewkeys() & dic8.viewkeys() & dic9.viewkeys() & dic10.viewkeys():
    manydics[k] = (dic1[k], dic2[k],dic3[k],dic4[k],dic5[k],dic6[k],dic7[k],dic8[k],dic9[k],dic10[k])

return manydics
请注意,我试图将参数dic3、dic4、dic5等等于“True”,因此当它们未指定且在函数中被调用时,不会发生任何事情。但是,我得到了以下错误:

Traceback (most recent call last):
File "/Users/File.py", line 616, in <module>
main_dic=merge_many_dics(dic1,dic2,dic3,dic4)
File "/Users/File.py", line 132, in merge_many_dics
& dic7.viewkeys() & dic8.viewkeys() & dic9.viewkeys() & dic10.viewkeys():
AttributeError: 'bool' object has no attribute 'viewkeys'
回溯(最近一次呼叫最后一次):
文件“/Users/File.py”,第616行,在
主dic=合并多个dic(dic1、dic2、dic3、dic4)
文件“/Users/File.py”,第132行,合并多个DIC
&dic7.viewkeys()&dic8.viewkeys()&dic9.viewkeys()&dic10.viewkeys():
AttributeError:“bool”对象没有属性“viewkeys”

有没有人可以点亮我的旅程?

您应该尝试args语法:

def merge_many_dics(*args):
   iterate over your args to join them
然后,您可以使用任意多的参数调用该函数

带有*args的函数可以如下所示:

   def print_all(name, *args):
      print "Hello", name, "here are your args"
      for arg in args:
         print arg

   print_all("Claus", "car", "boat", "house")
这将打印:

Hello Clause here are your args

car
boat
house

正如错误所说,您无法查看布尔值(也称为True)的键。viewkeys()不起作用。将默认词典更改为空,保留:

def merge_many_dics(dic1,dic2,dic3={},dic4={},dic5={},dic6={},dic7={},dic8={},dic9={},dic10={}):
    """
    Merging up to 10 dictionaries with same keys and different values
    :return: a dictionary containing the common dates as keys and both values as values
    """
    manydics = {}
    for k in dic1.viewkeys() & dic2.viewkeys() & dic3.viewkeys() & dic4.viewkeys() & dic5.viewkeys() & dic6.viewkeys()\
            & dic7.viewkeys() & dic8.viewkeys() & dic9.viewkeys() & dic10.viewkeys():
        manydics[k] = (dic1[k], dic2[k],dic3[k],dic4[k],dic5[k],dic6[k],dic7[k],dic8[k],dic9[k],dic10[k])

    return manydics
这里是一个实现,您可以为每个键创建一个列表并添加每个项,我相信它可以进行更多优化,但它非常可读:

def merge_many_dicts(*args):
    """
    Merging all dictionaries suposing all dictionaries share keys
    :return: a dictionary containing the common dates as keys and both values as values
    """
    manydicts = {}
    for k in args:
        for key in k.iterkeys():
            manydicts[key] = []
    for k in args:
        for key, value in k.iteritems():
            manydicts[key].append(value)

    return manydicts
使用,可以使用任意数量的参数调用函数:

>>> def merge_many_dics(*dicts):
...     common_keys = reduce(lambda a, b: a & b, (d.viewkeys() for d in dicts))
...     return {key: tuple(d[key] for d in dicts) for key in common_keys}
...
>>> merge_many_dics({1:2}, {1:3}, {1:4, 2:5})
{1: (2, 3, 4)}

您可以使用以下代码,在函数中初始化这些参数

def merge_many_dics(dic1, dic2, dic3=None, dic4=None, dic5=None, dic6=None, dic7=None, dic8=None, dic9=None,
                    dic10=None):
    """
    Merging up to 10 dictionaries with same keys and different values
    :return: a dictionary containing the common dates as keys and both values as values
    """
    for item in locals().items():
        if item is None:
            item = dic1

    manydics = {}
    for k in dic1.viewkeys() & dic2.viewkeys() & dic3.viewkeys() & dic4.viewkeys() & dic5.viewkeys() & dic6.viewkeys() \
            & dic7.viewkeys() & dic8.viewkeys() & dic9.viewkeys() & dic10.viewkeys():
        manydics[k] = (dic1[k], dic2[k], dic3[k], dic4[k], dic5[k], dic6[k], dic7[k], dic8[k], dic9[k], dic10[k])

    return manydics

下面是基于@falsetru answer并使用函数的Python3.x答案

>>> from functools import reduce
>>> import operator
>>> def merge_many_dicts(*dicts):
...     common_keys = reduce(operator.and_, (d.keys() for d in dicts))
...     return {key: tuple(d[key] for d in dicts) for key in common_keys}
... 
>>> merge_many_dicts({1:2}, {1:3}, {1:4, 2:5})
{1: (2, 3, 4)}

这是怎么回事?从未使用过*args,您能进一步解释一下吗?args是传递给函数的所有参数的列表。当您事先不知道将接收多少个参数时,可以使用它。我这样做了,并为函数定义了4个字典。因此,我得到了以下错误:NameError:未定义全局名称“dic5”。差距在哪里?您将使用数组中的dicts(即args)迭代args以访问传递的单个字典。您可以在函数中编写一个迭代args的示例吗?它可以工作,但函数将返回一个空字典,这不是我使用*args的意图,我将编辑我的回答从不使用可变的默认值。请参见使用
*args
或使用None作为默认值。@abutemutate如果使用
None
方法,则应在函数内部检查是否传递了参数。例如,如果dic3为None,则使用
;如果isinstance(dic3,dict),则使用
。但最好使用另一个答案中解释的
*args
。@DeepSpace:如链接所述,正确使用可变默认值非常有用。不过,我当然同意不应将它们用于类似的用途。因为在你的链接和中提到的问题,这是一个好主意™ 若要在使用可变默认参数.FWIW时显式注释所做的操作,
运算符.and.
是该
lambda
的替代方法