2015-12-13 16 views
10

Sto provando a creare una funzione che potrebbe ricevere come input molti o alcuni dizionari. Sto utilizzando il seguente codice:Funzione con i dizionari come argomenti opzionali - 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 

Si noti che sto cercando di eguagliare l'argomenti dic3, dic4, dic5 e così via per "True", in modo che quando non vengono specificati e sono chiamati nella funzione non accade nulla. Tuttavia sto ricevendo il seguente errore:

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' 

Chiunque può illuminare il mio viaggio disponibile?

risposta

13

Utilizzando arbitrary argument list, la funzione può essere chiamata con un numero arbitrario di argomenti:

>>> 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_' è un'alternativa alla soluzione in sospeso' lambda' –

+0

. Grazie – abutremutante

6

Si dovrebbe provare la sintassi args:

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

poi si può chiamare la funzione con il maggior numero di argomenti che vuoi.

Una funzione con args * potrebbe essere la seguente:

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

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

questo stampa:

Hello Clause here are your args 

car 
boat 
house 
+0

come funziona? mai usato * args, puoi spiegare un po 'oltre? – abutremutante

+0

args è un elenco di tutti gli argomenti passati alla funzione. Puoi usarlo quando non sai in anticipo quanti argomenti riceverai. – Randrian

+0

L'ho fatto e ho definito 4 dizionari per la funzione. Come risultato ottengo questo errore: NameError: il nome globale 'dic5' non è definito. Dov'è il divario? – abutremutante

0

Come dice l'errore, non è possibile visualizzare le chiavi di un valore booleano, alias, True. viewkeys() non funziona. Cambiare il dizionario di difetto di essere vuote, lasciando:

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 

Ecco un'implementazione in cui si crea una lista per ogni chiave e aggiunge ogni articolo, sono sicuro che può essere ottimizzata molto di più, ma è molto leggibile:

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

Funziona ma la funzione restituirà un dizionario vuoto e non è l'intenzione – abutremutante

+0

Vorrei andare con l'* args aproach, modifico la mia risposta – byrass

+0

grazie, non vedo l'ora – abutremutante

0

È possibile utilizzare il seguente codice, a siglare quelli parametro s con nella funzione

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

Ecco Python risposta 3.x in base alla risposta @falsetru e utilizzando la funzione di operator.and_.

>>> 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)} 
Problemi correlati