Отфильтруйте два списка словаря по 2 парам значений И сгруппируйте их вместе - PullRequest
0 голосов
/ 29 апреля 2018

У меня есть 2 списка словарей, скажем:

List_D1 = [{'Symbol':'GFX','Time':'9:36am', 'Change':-0.18, 'Volume':181800},
            {'Symbol':'AIG','Time':'9:36am', 'Change':-0.15, 'Volume': 195500},
            {'Symbol':'AXP','Time':'9:36am', 'Change':-0.46, 'Volume': 935000},
            ]
List_D2 = [{'Symbol':'AA','Time':'7:36am', 'Change':-0.08, 'Volume':181800},
            {'Symbol':'AIG','Time':'9:36am', 'Change':0.99, 'Volume': 197500},
            {'Symbol':'GFX','Time':'9:36am', 'Change':-0.46, 'Volume': 935000},
            ]

Я хочу выбрать элементы в отдельные списки с одинаковыми значениями «Символ» и «Время»: В приведенном выше примере это должно быть пара:

Пара 1:

List_D1 : {'Symbol':'AIG','Time':'9:36am', 'Change':-0.15, 'Volume': 195500} 
List_D2 : {'Symbol':'AIG','Time':'9:36am', 'Change':0.99, 'Volume': 197500}

Пара 2:

List_D1 :{'Symbol':'GFX','Time':'9:36am', 'Change':-0.18, 'Volume':181800}
List_D2 :{'Symbol':'GFX','Time':'9:36am', 'Change':-0.46, 'Volume': 935000}

Теперь я просто перебираю каждую запись в разных списках словаря, мне интересно, есть ли лучшая идея, чтобы сделать это более эффективно?

Я подумываю об использовании itemgetter до sort(List_D1+List_D2) в Python, а затем использовать функцию groupby для объединения всего отсортированного списка и групп, которые я хочу соединить вместе. Однако, делая это, я не могу сказать, какой элемент из каких списков.

Here is my source code :

from operator import itemgetter
from itertools import groupby

ListsBoth = List_D1+List_D2

key1 = 'Symbol' 
key2 = 'Time'
grouper = itemgetter(key1,key2)
ResuListx2.sort(key=grouper)
for key, testItem in groupby(ListsBoth,key=grouper):
        // here I can group all items with same 'Symbol' AND 'Time' value together, but just missed the original "List" info - where each item in same group comes from. but I need it for my application.
    ...... handle each item in testItem ()

Ответы [ 3 ]

0 голосов
/ 29 апреля 2018
List_D1 = [{'Symbol': 'GFX', 'Time': '9:36am', 'Change': -0.18, 'Volume': 181800},
           {'Symbol': 'AIG', 'Time': '9:36am', 'Change': -0.15, 'Volume': 195500},
           {'Symbol': 'AXP', 'Time': '9:36am', 'Change': -0.46, 'Volume': 935000},
           ]
List_D2 = [{'Symbol': 'AA', 'Time': '7:36am', 'Change': -0.08, 'Volume': 181800},
           {'Symbol': 'AIG', 'Time': '9:36am', 'Change': 0.99, 'Volume': 197500},
           {'Symbol': 'GFX', 'Time': '9:36am', 'Change': -0.46, 'Volume': 935000},
           ]

b = map(lambda x: x.get('Symbol') + '_' + x.get('Time'), List_D1)
c = map(lambda x: x.get('Symbol') + '_' + x.get('Time'), List_D2)
e = map(lambda x: (List_D1[b.index(x)], List_D2[c.index(x)]), set(b) & set(c))
for i in e:
    print(i)
0 голосов
/ 29 апреля 2018

Вы также можете использовать itertools.groupby, а затем сохранять только результаты с более чем одним результирующим элементом:

import itertools
List_D1 = [{'Symbol':'GFX','Time':'9:36am', 'Change':-0.18, 'Volume':181800},
        {'Symbol':'AIG','Time':'9:36am', 'Change':-0.15, 'Volume': 195500},
        {'Symbol':'AXP','Time':'9:36am', 'Change':-0.46, 'Volume': 935000},
        ]
List_D2 = [{'Symbol':'AA','Time':'7:36am', 'Change':-0.08, 'Volume':181800},
        {'Symbol':'AIG','Time':'9:36am', 'Change':0.99, 'Volume': 197500},
        {'Symbol':'GFX','Time':'9:36am', 'Change':-0.46, 'Volume': 935000},
        ]
d = [(a, list(b)) for a, b in itertools.groupby(sorted(List_D1+List_D2, key=lambda x:(x['Symbol'], x['Time'])), key=lambda x:(x['Symbol'], x['Time']))]
final_data = {a:b for a, b in d if len(b) > 1}

Выход:

{('AIG', '9:36am'): [{'Symbol': 'AIG', 'Time': '9:36am', 'Change': -0.15, 'Volume': 195500}, {'Symbol': 'AIG', 'Time': '9:36am', 'Change': 0.99, 'Volume': 197500}], ('GFX', '9:36am'): [{'Symbol': 'GFX', 'Time': '9:36am', 'Change': -0.18, 'Volume': 181800}, {'Symbol': 'GFX', 'Time': '9:36am', 'Change': -0.46, 'Volume': 935000}]}
0 голосов
/ 29 апреля 2018

Вы можете преобразовать каждый список диктов в диктовку с кортежем символа и времени в качестве ключа, а затем выполнить простой поиск по обоим, чтобы создать пары, которые вы ищете, например ::100100

In []:
D1 = {(d['Symbol'], d['Time']): d for d in List_D1}
D2 = {(d['Symbol'], d['Time']): d for d in List_D2}
[(D1.get(k, None), D2.get(k, None)) for k in set(D1) | set(D2)]

Out[]:
[({'Change': -0.18, 'Symbol': 'GFX', 'Time': '9:36am', 'Volume': 181800},
  {'Change': -0.46, 'Symbol': 'GFX', 'Time': '9:36am', 'Volume': 935000}),
 ({'Change': -0.15, 'Symbol': 'AIG', 'Time': '9:36am', 'Volume': 195500},
  {'Change': 0.99, 'Symbol': 'AIG', 'Time': '9:36am', 'Volume': 197500}),
 ({'Change': -0.46, 'Symbol': 'AXP', 'Time': '9:36am', 'Volume': 935000}, None),
 (None, {'Change': -0.08, 'Symbol': 'AA', 'Time': '7:36am', 'Volume': 181800})]

Вы можете устранить любые несопоставимые пары, изменив его на:

[(D1[k], D2[k]) for k in D1 if k in D2]

Теперь вы можете выполнять итерацию каждой пары, выполняя то, что вам нужно, например ::100100

In []:
results = [(D1[k], D2[k]) for k in D1 if k in D2]
for l1, l2 in results:
    print(l1, l2)

Out[]:
{'Symbol': 'GFX', 'Time': '9:36am', 'Change': -0.18, 'Volume': 181800} {'Symbol': 'GFX', 'Time': '9:36am', 'Change': -0.46, 'Volume': 935000}
{'Symbol': 'AIG', 'Time': '9:36am', 'Change': -0.15, 'Volume': 195500} {'Symbol': 'AIG', 'Time': '9:36am', 'Change': 0.99, 'Volume': 197500}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...