2009-03-10 16 views
5

Sto cercando di velocizzare l'uso dei dizionari. Ho passato tre ore la scorsa notte a cercare sul web esempi simili a quelli che sto cercando di fare. Ad esempio, supponiamo di avere due dizionari (in realtà ho due elenchi di dizionari).Dizionari in Python

d1={key1:1, key2:2} 
d2={key1:1, key2:'A', key4:4} 

voglio aggiornare d1 in modo che appaia simile al seguente:

d1={key1:1, key2:[2,'A'], key3:3, key4:4} 

II non riesco a trovare esempi adeguati per ottenerlo iniziato. Ho un buon numero di libri e li ho anche rivisti, ma sembrano tutti avere lo stesso tipo di esempi che sto trovando sul web.

Qualcuno conosce un luogo o un libro con esempi e descrizioni espliciti di come utilizzare i dizionari?

Penso che uno dei problemi che sto avendo è che non capisco come vengono mantenuti i riferimenti man mano che accedo al dizionario.

posso controllare per vedere se i due dizionari hanno una chiave comune:

for k in d1.keys(): 
    for k2 in d2.keys(): 
     if k==k2: 
      print 'true' 

ma se lo fanno io non riesco a combinare i valori in una lista.

Più che una risposta diretta a questo particolare esempio, gradirei qualsiasi suggerimento sui luoghi in cui ci sono buoni esempi di utilizzo dei dizionari.

+1

Dovresti davvero usare un titolo più descrittivo per questa domanda. –

+1

da dove proviene key3? – SilentGhost

risposta

6

Un buon punto di partenza è ottenendo ipython (easy_install ipython) poi a frugare con il completamento scheda, ? e dir:

In [2]: dir {} 
------> dir({}) 

Out[2]: 
['__class__', 
... 
'keys', 
'pop', 
'popitem', 
'setdefault', 
'update', 
'values'] 

In [3]: {}.update? 
Type:  dict 
Base Class: <type 'dict'> 
String Form: {} 
Namespace: Interactive 
Length:  0 
Docstring: 
    dict() -> new empty dictionary. 
    dict(mapping) -> new dictionary initialized from a mapping object's 
     (key, value) pairs. 
    dict(seq) -> new dictionary initialized as if via: 
     d = {} 
     for k, v in seq: 
      d[k] = v 
    dict(**kwargs) -> new dictionary initialized with the name=value pairs 
     in the keyword argument list. For example: dict(one=1, two=2) 

(solo per esempio)

In ogni caso, il tuo problema con il controllo dei tasti è comune tra i due dizionari: ci sono alcune cose da considerare (forse guarda la classe set?), Ma ecco come lo farei:

common_keys = [k for k in dict1 if k in dict2] 

(cioè, "ogni tasto k in dict1 se quella chiave è anche in dict2") (si noti, inoltre, che i test per l'adesione dizionario è un O (1) il funzionamento, quindi questo verrà eseguito in O (| dict1 |))

modificare: va bene, quindi questo non risolve il problema di fondere le due dicts in uno con le liste ... Ma la risposta di Lott è buono per quello, oppure è possibile utilizzare il metodo setdefault:

new = {} 
for (k, v) in dict1.items(): 
    new.setdefault(k, []).append(v) 
for (k, v) in dict2.items(): 
    new.setdefault(k, []).append(v) 
+0

Si sta suggerendo ipython per il completamento della tabulazione? Ignorare il completamento di questo tab è dannoso per l'apprendimento, e che ipython è in genere dannoso per l'apprendimento e inoltre assolutamente non necessario? Digli solo di leggere i documenti. –

+0

è semplicemente folle – SilentGhost

+0

Il completamento delle schede è uno dei motivi per cui mi piace iPython. Un paio degli altri, che ho dimostrato qui, sono il "?" funzione e la chiamata-senza-genitori. –

14

Prova questa:

import collections 
merged = collections.defaultdict(list) 
for k in d1: 
    merged[k].append(d1[k]) 
for k in d2: 
    merged[k].append(d2[k]) 

Questo può essere quello che stai cercando.

O forse questo.

import collections 
merged = collections.defaultdict(set) 
for k in d1: 
    merged[k].add(d1[k]) 
for k in d2: 
    merged[k].add(d2[k]) 
+0

che crea una lista per ogni elemento, e fa corrispondenze esatte "duplicate" – SilentGhost

+0

@SilentGhost: Giusto. È molto più semplice del dizionario "ibrido" con un miscuglio di singleton e liste. –

+0

È possibile evitare corrispondenze duplicate utilizzando defaultdict (set) – Algorias

1

Python dizionari di lavorare anche molto simile array associativi in ​​PHP, se avete qualche esperienza in quella lingua.

Il Built-in pagina Tipi nella documentazione Python ha anche una buona sezione sui dizionari, e la sezione ha anche un elenco delle funzioni disponibili per loro:

http://docs.python.org/library/stdtypes.html#mapping-types-dict

4

Credo che qui è quello che volete:

>>> d1={'key1':1, 'key2':2} 
>>> d2={'key1':1, 'key2':'A', 'key4':4} 
>>> d = {} 
>>> d.update(d1) 
>>> for i in d2: 
     if i in d and d2[i] != d[i]: 
      d[i] = [d[i], d2[i]] 
     else: 
      d[i] = d2[i]    
>>> d 
{'key2': [2, 'A'], 'key1': 1, 'key4': 4} 
+0

+1: l'unica risposta che produce dizionari nel formato della domanda. – jfs

+0

Tuttavia, non generalizza molto bene. –

+0

@ S.Lott: deve? soddisfa i requisiti e funziona velocemente. prendilo tutti i giorni :) – SilentGhost

0

bene, per il primo caso, si potrebbe desiderare un aiutante che combina due oggetti in una lista di due oggetti, e due liste in una lista contenente gli elementi dalla due liste,

Ciò presuppone, naturalmente, che si uniscono sempre chiavi in ​​liste, ma non si vuole le chiavi di finire per essere "gli elenchi di liste"

def listify(obj): 
    if type(obj) != type([]): return [obj] 
    else: return obj 

def merge(v1, v2): 
    return listify(v1) + listify(v2) 

#so now you can merge two dictionaries: 
dict1 = dict(a = 2, b = 5, c = 7) 
dict2 = dict(b = 4, d = 9, f = 10) 
dikt = {} 

for k in set(dict1.keys() + dict2.keys()): 
    dikt[k] = merge(dict1.get(k, []), dict2.get(k, [])) 
#resutls in: 
# {'a': [2], 'c': [7], 'b': [5, 4], 'd': [9], 'f': [10]} 

si può notare, dict.keys() restituisce un elenco di chiavi, set restituisce una lista senza elementi duplicati, in modo set(d1.keys(), d2.keys()) rendimenti unione delle chiavi di D1 e D2

0

Una variazione sul @SilentGhost's answer (tutte le altre risposte producono dizionari sbagliate):

>>> d1 = dict(key1=1, key2=2) 
>>> d2 = dict(key1=1, key2='A', key4=4) 
>>> d = dict(d1) 
>>> for k, v2 in d2.iteritems(): 
...  v = d.get(k, None) 
...  d[k] = [v, v2] if v is not None and v != v2 else v2 
... 
>>> d 
{'key2': [2, 'A'], 'key1': 1, 'key4': 4} 
0

forse questo è un po 'imbarazzante fare perché la struttura dati che stai cercando di creare non è naturale come potrebbe essere. Ad esempio, invece di avere alcuni valori come valori solitari, e alcuni sono elenchi, perché non tenere tutto negli elenchi? Per esempio.

{'key1': [1], 'key2': [2, 'A'], 'key4': [4]} 

È possibile in Python avere una raccolta di tipi di dati misti, ma il codice sarà spesso più pulito se lo si mantiene coerente. Se si utilizza questo tipo di struttura dati, inserimento è facile come

# Inserting a (key, value) pair 
if key in my_dict: 
    my_dict[key].append(value) 
else: 
    my_dict[key] = [value] 
0

Ecco un'altra variazione.

d1 = {'key1'=1, 'key2'=2} 
d2 = {'key1'=1, 'key2'='A', 'key4'=4) 
d = d2 
for k, v in d.iteritems(): 
... if k in d1.keys() and v!=d1[k]: 
... d[k] = [d1[k], v2] 
d 
{'key2': [2, 'A'], 'key1': 1, 'key4': 4} 
Problemi correlati