2015-12-13 13 views
10

Ich versuche, eine Funktion zu erstellen, die als Eingabe viele oder einige Wörterbücher erhalten könnte. Ich verwende den folgenden Code:Funktion mit Wörterbüchern als optionale Argumente - Python

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 

Bitte beachte, dass ich versuche, die Argumente dic3, DIC4, dic5 zu entsprechen und so weiter auf „True“, so dass, wenn sie nicht angegeben werden und werden in der Funktion aufgerufen nichts passiert. Allerdings bekomme ich den folgenden Fehler:

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' 

Jeder meine Reise zur Verfügung zu beleuchten?

Antwort

13

arbitrary argument list Verwendung, kann die Funktion mit einer beliebigen Anzahl von Argumenten aufgerufen werden:

>>> 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)} 
+0

FWIW, "operator.and_" ist eine Alternative zu dieser "Lambda" –

+0

herausragende Lösung. Vielen Dank – abutremutante

6

Sie sollten die args Syntax versuchen:

def merge_many_dics(*args): 
    iterate over your args to join them 

dann können Sie die Funktion mit so vielen Argumente nennen, wie Sie wollen.

Eine Funktion mit * args könnte wie folgt aussehen:

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

    print_all("Claus", "car", "boat", "house") 

diese gedruckt werden:

Hello Clause here are your args 

car 
boat 
house 
+0

wie funktioniert das? nie benutzt * Argumente, können Sie ein bisschen weiter erklären? – abutremutante

+0

args ist eine Liste aller Argumente, die an die Funktion übergeben werden. Sie können es verwenden, wenn Sie nicht im Voraus wissen, wie viele Argumente Sie erhalten werden. – Randrian

+0

Ich habe es gemacht und 4 Wörterbücher für die Funktion definiert. Als Ergebnis bekomme ich diesen Fehler: NameError: globaler Name 'dic5' ist nicht definiert. Wo ist die Lücke? – abutremutante

0

Wie der Fehler sagt, können Sie die Tasten eines boolean nicht sehen können, auch bekannt als, True. viewkeys() funktioniert nicht. Ändern des Standard Wörterbuch des leer sein, so dass:

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 

Hier ist eine Implementierung in dem Sie eine Liste für jeden Schlüssel erstellen und jedes Element hinzufügen, ich bin sicher, es kann viel mehr optimiert werden, aber es ist sehr lesbar:

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 
+0

Es funktioniert, aber die Funktion wird ein leeres Wörterbuch zurückgeben und das ist nicht die Absicht – abutremutante

+0

Ich würde mit dem * args aproach gehen, werde ich meine Antwort bearbeiten – byrass

+0

danke, freue mich darauf – abutremutante

0

Sie den folgenden Code verwenden können, diejenigen Parameter initial s mit in der Funktion

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 
4

Hier ist Python 3.x Antwort basierend auf @falsetru Antwort und mit der operator.and_ Funktion.

>>> 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)} 
Verwandte Themen