0

Good eveneing, I want to merge two lists of dictonaries if they have the same key:value in it. Its like a join in SQL. I'm not allowed to import any modules for this problem.

Here an example:

Input:

>>> series = [
... {'s_id': 'bb', 'title': 'Breaking Bad'},
... {'s_id': 'bcs', 'title': 'Better Call Saul'}]

>>> series_characters = [
... {'c_id': 'ww', 's_id': 'bb'},
... {'c_id': 'sw', 's_id': 'bb'}, 
... {'c_id': 'sg', 's_id': 'bb'}
... {'c_id': 'sg', 's_id': 'bcs'}

Output should be a list of dicts with both infomration inside it:

out= [
{'s_id': 'bb', 'title': 'Breaking Bad', 'c_id': 'ww'},
{'s_id': 'bcs', 'title': 'Better Call Saul', 'c_id': 'sg'}]

I tried somthing like that but I think that my thoughts are to complicated and the code doesen't work:

def _join(tbl1, tbl2):
    """
    Helping function to merge two tables inform of a list

    Argurments:
        tbl1 (list): list of dict's containung a table
        tbl2 (list): list of dict's containung a table
    Returns:
        back_lst (list): list, containing wanted rows of the table

    """
    back_lst = []
    for element1 in tbl1:
        for element2 in tbl2:
            for key in tbl1[element1]:
                if tbl1[element1[key]] == tbl2[element2[key]]:
                    a = tbl1[element1].copy()
                    a.update(tbl2[element2])
                    back_lst.append(a)
    return back_lst

It would be nice to get some help here. Thanks in advance.

2
  • 1
    in series_charachter for s_id bb, the c_id is ww ,sw, sg then why did it only merge with sg not other? Commented Dec 5, 2016 at 18:39
  • @harshil9968 good point, also it should be noted what if there are more than one common keys e.g. in SQL where tbl1.name=tbl2.name and tbl1.id=tbl2.id. Commented Dec 5, 2016 at 18:47

3 Answers 3

3

Given all of your keys are just strings you can do:

>>> [dict(a, **b) for a in series_characters for b in series if a['s_id'] == b['s_id']]
[{'c_id': 'ww', 's_id': 'bb', 'title': 'Breaking Bad'},
 {'c_id': 'sw', 's_id': 'bb', 'title': 'Breaking Bad'},
 {'c_id': 'sg', 's_id': 'bb', 'title': 'Breaking Bad'},
 {'c_id': 'sg', 's_id': 'bcs', 'title': 'Better Call Saul'}]​
Sign up to request clarification or add additional context in comments.

Comments

0

You don't want to be doing tbl1[element1], assuming that tbl1 is a list of dicts. element1 should already be the dict you want, so just do element1.copy(). Same for indexing tbl2.

Comments

0
# your code goes here

def joinTable( tbl1, tbl2 ):
    op = []
    if len( tbl1 )  > 0 and len( tbl2 ) > 0:
        keys = set( tbl1[0].keys()).intersection( tbl2[0].keys())
        opkeys = set( tbl1[0].keys()).union( tbl2[0].keys())
        for row1 in tbl1:
            key1 = set( row1.keys())
            for row2 in tbl2:
                key2 = set( row2.keys())
                assert key1.intersection( key2 ) == keys
                assert key1.union( key2 ) == opkeys
                match = True
                for key in keys:
                    match = row1[ key] == row2[key]
                if match:
                    d = dict()
                    for key in opkeys:
                        d[ key ] = row1[ key ]  if key in row1 else row2[key]
                    op.append( d )
    return op

print joinTable( [{'s_id': 'bb', 'title': 'Breaking Bad'},{'s_id': 'bcs', 'title': 'Better Call Saul'}],[
{'c_id': 'ww', 's_id': 'bb'},{'c_id': 'sw', 's_id': 'bb'}, {'c_id': 'sg', 's_id': 'bb'},{'c_id': 'sg', 's_id': 'bcs'}])

Ideone

It implements the join algorithm of SQL. Something similar to https://blogs.msdn.microsoft.com/craigfr/2006/08/03/merge-join/ .

You can further extends this to like particular key and restrict value as well.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.