2013-07-11 20 views
6

Powiązane: Is there any pythonic way to combine two dicts (adding values for keys that appear in both)?Python - Połączyć dwa słowniki, połączyć wartości ciągów?

Chciałbym połączyć dwa ciągi: słowniki napisów i połączyć wartości. Powyższy post zaleca używanie collections.Counter, ale nie obsługuje on łączenia ciągów.

>>> from collections import Counter 
>>> a = Counter({'foo':'bar', 'baz':'bazbaz'}) 
>>> b = Counter({'foo':'baz'}) 
>>> a + b 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/collections.py", line 569, in __add__ 
TypeError: cannot concatenate 'str' and 'int' objects 

(Domyślam się, Counter próbuje ustawić b['baz'] do 0.)

Chciałbym uzyskać wynik {'foo':'barbaz', 'baz':'bazbaz'}. Kolejność konkatenacji nie ma dla mnie znaczenia. Jaki jest czysty, Pythonowy sposób na zrobienie tego?

+0

Jakie będą oczekiwane wyniki, jeśli pojawi się drugi dyktat: '{'foo': 'baz', 'spam': 'jaja'}'? –

+0

@AshwiniChaudhary {'foo': 'barbaz', 'baz': 'bazbaz', 'spam': 'eggs'} – jbreed

Odpowiedz

14

Dict-zrozumieniem:

>>> d = {'foo': 'bar', 'baz': 'bazbaz'} 
>>> d1 = {'foo': 'baz'} 
>>> keys = d.viewkeys() | d1.viewkeys() 
>>> {k : d.get(k, '') + d1.get(k, '') for k in keys} 
{'foo': 'barbaz', 'baz': 'bazbaz'} 

dla Pythona 2.6 i wcześniejsze:

>>> dict((k, d.get(k, '') + d1.get(k, '')) for k in keys) 
{'foo': 'barbaz', 'baz': 'bazbaz'} 

To będzie pracować dla dowolnej liczby dicts:

def func(*dicts): 
    keys = set().union(*dicts) 
    return {k: "".join(dic.get(k, '') for dic in dicts) for k in keys} 
... 
>>> d = {'foo': 'bar', 'baz': 'bazbaz'} 
>>> d1 = {'foo': 'baz','spam': 'eggs'} 
>>> d2 = {'foo': 'foofoo', 'spam': 'bar'} 
>>> func(d, d1, d2) 
{'foo': 'barbazfoofoo', 'baz': 'bazbaz', 'spam': 'eggsbar'} 
+0

Zrozumienie słownika, to pierwsze, co słyszałem, ale brzmi świetnie! –

0

można zapisać rodzajowe pomocnika, takie jak:

a = {'foo':'bar', 'baz':'bazbaz'} 
b = {'foo':'baz'} 

def concatd(*dicts): 
    if not dicts: 
     return {} # or should this be None or an exception? 
    fst = dicts[0] 
    return {k: ''.join(d.get(k, '') for d in dicts) for k in fst} 

print concatd(a, b) 
# {'foo': 'barbaz', 'baz': 'bazbaz'} 

c = {'foo': '**not more foo!**'} 
print concatd(a, b, c) 
# {'foo': 'barbaz**not more foo!**', 'baz': 'bazbaz'}