2016-12-05 3 views
0

Хорошо, Я хочу объединить два списка диктаторов, если они имеют одинаковый ключ: значение в нем. Это похоже на объединение в SQL. Мне не разрешено импортировать какие-либо модули для этой проблемы.Объединить два списка словарей с одинаковым ключом: значение в python

Вот пример:

Вход:

>>> 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'} 

Вывод должен быть список dicts как с infomration внутри него:

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

Я пытался Somthing так, но я думаю, что мои мысли сложны и код не работает:

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 

Было бы неплохо получить помощь здесь. Заранее спасибо.

+1

в серии_charachter для s_id bb, c_id ww, sw, sg, тогда почему он только слился с sg не другим? – harshil9968

+0

@ harshil9968 хорошая точка, также следует отметить, что, если имеется более одного общего ключа, например. в SQL, где tbl1.name = tbl2.name и tbl1.id = tbl2.id. –

ответ

0

Вы не хотите делать tbl1[element1], считая, что tbl1 - это список dicts. element1 должен уже быть диктором, которого вы хотите, поэтому просто сделайте element1.copy(). То же самое для индексации tbl2.

+0

Вы правы, спасибо за подсказку! –

3

Учитывая все ключи только строки, которые вы можете сделать:

>>> [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'}]​ 
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

Он реализует алгоритм Присоеденяйтесь SQL. Нечто похожее на https://blogs.msdn.microsoft.com/craigfr/2006/08/03/merge-join/.

Вы также можете расширить это, как конкретный ключ, и ограничить его.

Смежные вопросы