Объединить два списка словарей с одинаковым ключом: значение в Python

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

Вот пример:

Входные данные:

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

Вывод должен быть списком диктов с информацией внутри:

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

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

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

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

3 ответа

Решение

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

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

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

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

Другие вопросы по тегам