Извлечение данных из нескольких словарей - PullRequest
0 голосов
/ 27 января 2012

Мои структуры данных:

phase1_hits = {
    '1.2.3.4': {'hits': 3, 'internal': '10.28.30.153', 'public_additional': ['8.2.17.14'], 'list': 'Red', 'internal_additional': ['10.17.100.74', '10.19.70.77', '10.28.30.153']},
    '2.3.4.5': {'hits': 19, 'internal': '10.19.40.175', 'public_additional': ['1.2.227.49'], 'list': 'Red', 'internal_additional': ['10.19.40.175']},
    '12.23.34.45': {'hits': 52, 'internal': '192.168.164.32', 'public_additional': ['8.2.17.14'], 'list': 'Orange', 'internal_additional': ['192.168.164.32', '192.168.164.42', '192.168.164.49']},
    '8.8.8.8': {'hits': 5, 'internal': '192.168.1.10', 'public_additional': ['8.8.87.153', '1.2.3.4'], 'list': 'Green', 'internal_additional': ['192.168.168.250']}
}


phase2_hits = {
    97536: {'ip.dst': ['8.2.17.14'], 'ip.src': ['10.28.30.153']},
    60096: {'ip.dst': ['8.2.17.14'], 'ip.src': ['192.168.164.42']}, 
    43140: {'ip.dst': ['8.2.17.9'], 'ip.src': ['10.153.134.201']},
    43789: {'ip.dst': ['10.28.30.153'], 'ip.src': ['8.2.17.9']},
    89415: {'ip.dst': ['8.2.17.14'], 'ip.src': ['10.153.134.200']}
}

Факты о структуре данных (может быть, ничего из этого не имеет значения ??):

  • ключ phase1_hits всегда будет публичным IP
  • phase1_hits public_additional и internal_additional может быть пустым
  • phase2_hits частные IP-адреса могут появляться в ip.src или .dst
  • phase2_hits ip.src и .dst всегда будут иметь только один элемент в списке (да, я знаю, что это глупая структура, но я не могу ее контролировать)
  • поскольку частный IP-адрес появляется в phase1_hits, это не значит, что он будет отображаться в phase2_hits, поэтому, если это не так, мне нужна только информация о phase1_hits

Если IP-адрес phase1_hits для внутреннего или внутреннего IP-адреса виден в phase2_hits, я хочу извлечь соответствующий:

  • ключ phase1_hits
  • phase1_hits internal (или internal_additional - в зависимости от того, что было замечено в phase2_hits)
  • phase1_hits hit
  • phase1_hits list
  • ключ phase2_hits
  • phase2_hits ip.src или .dst (в зависимости от того, какой адрес противоположен внутреннему или внутреннему дополнительному адресу, который запрашивается)

Ключевая концепция извлечения состоит в том, чтобы сопоставить, какие частные IP-адреса говорили с какими-либо общедоступными IP-адресами. Также, если это поможет, я могу реструктурировать phase1_hits и использовать другой ключ.

1 Ответ

1 голос
/ 27 января 2012
matches = []
for ip1 in phase1_hits:
    subdict1 = phase1_hits[ip1]
    internal_ips = [subdict1['internal']] + subdict1['internal_additional']
    hits = subdict1['hits']
    color_list = subdict1['list']
    for ip2 in phase2_hits:
        subdict2 = phase2_hits[ip2]
        phase2_ips = subdict2['ip.dst'] + subdict2['ip.src']
        overlap = [i for i in internal_ips if i in phase2_ips]
        if len(overlap) > 0:
            temp = (ip1, overlap, hits, color_list, ip2, [i for i in phase2_ips if i in overlap])
            matches.append(temp)

Вот объяснение:

matches = []

Вам необходимо хранить данные где-то, где вы сможете изменить / использовать их позже. Список является самым простым, поскольку он может легко изменять размер в соответствии с имеющимися у вас данными и количеством изменяющихся элементов. Хотя словарь выполним, он не будет очень эффективным, особенно если вы ищете одиночные совпадения и не пытаетесь создать указатели на конкретные данные.

for ip1 in phase1_hits:

Вы можете перемещаться по клавишам в словаре, рассматривая его как список (т. Е. Вызывать функцию .keys() не нужно, поскольку вы не меняете / удаляете ключи в словаре).

    subdict1 = phase1_hits[ip1]
    internal_ips = [subdict1['internal']] + subdict1['internal_additional']
    hits = subdict1['hits']
    color_list = subdict1['list']

Я добавил псевдоним для удобства чтения; это, однако, не обязательно. В следующей строке я воспользовался собственным списком Python __add__, который просто добавляет элементы одного списка к другому и создает новый список, потому что internal_ips может иногда иметь несколько элементов. Затем, поскольку вы хотите получить число hits и значение 'list' в поддикте, я создал color_list. Обратите внимание, что я не назвал его так же, как ключ, потому что это конфликтовало бы с собственным пространством имен Python для типа переменной list.

    for ip2 in phase2_hits:
        subdict2 = phase2_hits[ip2]
        phase2_ips = subdict2['ip.dst'] + subdict2['ip.src']
        overlap = [i for i in internal_ips if i in phase2_ips]

Единственная новая вещь здесь - overlap. Используя генератор списков, мы можем найти все перекрывающиеся значения (отсюда и название). Вы можете называть это как хотите; просто знайте, что он будет заполнен всеми общими ценностями между ними. (Вы также можете использовать это: формула в основном [i for i in L1 if i in L2], где L1 и L2 оба списка.)

        if len(overlap) > 0:
            temp = (ip1, overlap, hits, color_list, ip2, [i for i in phase2_ips if i in overlap])
            matches.append(temp)

Оператор if гарантирует, что существует как минимум одно перекрытие между phase1_hits внутренним или внутренним_дополнительным IP и phase2_hits. Если это так, он будет заполнять кортеж (который является неизменным) на основе этой информации. (Я выбрал кортеж, поскольку он неизменен, и вы знаете его структуру, но вы можете изменить его в список, если хотите.) После заполнения он добавляется в список matches.

После прохождения обоих циклов у вас должно быть то, что вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...