4

I've data

stat=[{'state': {'europe': ['germany', 'england']}}, 
      {'state': {'europe': ['french', 'netherland']}},
      {'state': {'asian': ['japan', 'china']}}]

Question: how to join between the list ? Given result:

{'state': [{'europe': ['germany', 'england', 'french', 'netherland']}, 
           {'asian': ['japan', 'china']}]}

i'm using Python S60 with Python 2.2

jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • 5
    Python 2.2? Surely you can upgrade... – TerryA Jun 10 '13 at 01:01
  • Are you sure you want a list of single-item dicts, rather than one dict with multiple items? Unless you have external constraints, that's a rather odd data structure to use. – Zero Piraeus Jun 10 '13 at 01:09

3 Answers3

3

A naive try:

r={}
for d in stat:
    for k,v in d.iteritems():
        nd = r.setdefault(k,[])
        for tdk,tdv in v.iteritems():
            q = filter(lambda x: tdk in x.iterkeys(),nd)
            if not q:
                q = {tdk:[]}
                nd.append(q)
            else: q = q[0]
            q[tdk]+=tdv


print r
# prints {'state': [{'europe': ['germany', 'england', 'french', 'netherland']}, {'asian': ['japan', 'china']}]}
mshsayem
  • 17,557
  • 11
  • 61
  • 69
1

In python 2.2:

stat2 = {}
for s in stat:
    for c in s.values():
        for k, v in c.items():
            if k in stat2:
                stat2[k] += v
            else:
                stat2[k] = v  # perhaps copying here

stat2
{'asian': ['japan', 'china'],
 'europe': ['germany', 'england', 'french', 'netherland']}

If you were using python > 2.4, you could just use a defaultdict:

from collections import defaultdict
stat2 = defaultdict(list)

for s in stat:
    for c in s.values():
        for k, v in c.items():
            stat2[k] += v

stat2
defaultdict(<type 'list'>, {'europe': ['germany', 'england', 'french', 'netherland'], 'asian': ['japan', 'china']})

And if you really wanted:

{'state': [dict(stat2)]}
{'state': [{'asian': ['japan', 'china'],
   'europe': ['germany', 'england', 'french', 'netherland']}]}

Consider upgrading your python version, 2.2 was released in 2001...!

Andy Hayden
  • 359,921
  • 101
  • 625
  • 535
1

Here's a simple answer, using constructs available in Python 2.2, nothing fancy:

ans = {}
for d1 in stat:
    for k1, v1 in d1.items():
        if k1 not in ans:
            ans[k1] = []
        for k2, v2 in v1.items():
            for d2 in ans[k1]:
                if k2 in d2.keys():
                    d2[k2].extend(v2)
                    break
            else:
                ans[k1].append({k2:v2})

The result is as expected:

ans
=> {'state': [{'europe': ['germany', 'england', 'french', 'netherland']},
              {'asian' : ['japan', 'china']}]}
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • 1
    Probably worth pointing out that this doesn't produce what OP actually asked for (a list of single-key dicts) - although obviously it's a better data structure, all else being equal. – Zero Piraeus Jun 10 '13 at 01:23
  • @ZeroPiraeus you're right. I fixed it, now the result is as expected! – Óscar López Jun 10 '13 at 01:43