Как перебрать два списка словарей, чтобы добавить уникальные значения ключа в один список и продолжить через другой с общими повторяющимися записями значений? - PullRequest
0 голосов
/ 29 марта 2019

У меня возникают проблемы с выяснением того, как объединить уникальные значения ключей из одного списка в другой список, в котором словари имеют повторяющиеся значения.

Два списка создаются из разных источников, которые имеют некоторыеповторение значений «имя» и не всегда следовать одному и тому же индексу.Таким образом, бывают случаи, когда коррелирующий набор значений ключей появляется в одном списке и далее в его индексе (или, возможно, раньше).Кроме того, два списка списка могут не совпадать по длине с одним, содержащим больше записей, чем другим.

Я пробовал несколько вложенных циклов, но я не могу понять, как обрабатывать одновременное индексированиеи перезапуск цикла для объектов, которые еще не сопоставлены.Я также получил бы ошибку в конце из-за несоответствия диапазона в словарях списка.

Вот что я попробовал:

listOne = [{'name': 'Article 1 series', 'description': 'aaa'},
           {'name': 'Article 2', 'description': 'bbb'},
           {'name': 'Article 1 series', 'description': 'abb'},
           {'name': 'Article 3 series', 'description': 'cccc'}]

listTwo = [{'name': 'Article 1 series', 'link': 'www.google.com'},
           {'name': 'Article 2', 'link': 'www.yahoo.com'},
           {'name': 'Article 3 series', 'link': 'www.bing.com'},
           {'name': 'Article 1 series', 'link': 'www.google.com/test'},
           {'name': 'Article 4', 'link': 'www.duckduckgo.com'}]

firstList = len(listOne)
secondList = len(listTwo)

while listTwo:    
     for i in range(firstList):
         if i <= secondList:
             if listOne[i]["name"] == listTwo[0]["name"]:
                 print("found")
                 listOne.append(listTwo[0]["link"])
             else:
                 continue
         else:
             break
     listTwo.pop(0)

В конечном счете, так как значения ключей "name" совпадают, яхотелось бы объединить значение ключа "ссылка" в соответствующий найденный индекс listOne.В противном случае ищите предыдущее несоответствующее или следующее соответствующее значение ключа «name».Если в listOne нет значения ключа «name» или все индексы в listOne совпадают, остановите цикл и удалите все оставшиеся значения из listTwo.

Таким образом, listOne должен выглядеть следующим образом:

listOne = [{'name': 'Article 1 series', 'description': 'aaa','link': 'www.google.com'},
           {'name': 'Article 2', 'description': 'bbb', 'link': 'www.yahoo.com'},
           {'name': 'Article 1 series', 'description': 'abb', 'link': 'www.google.com/test'},
           {'name': 'Article 3 series', 'description': 'cccc', 'link': 'www.bing.com'}]

Ответы [ 3 ]

0 голосов
/ 29 марта 2019

Если у вас огромные списки, тогда начинайте использовать панд

from pandas as pd
one_df = pd.DataFrame(listOne)

OUTPUT:
  description              name
0         aaa  Article 1 series
1         bbb         Article 2
2         abb  Article 1 series
3        cccc  Article 3 series


second_df = pd.DataFrame(listTwo)

OUTPUT:
                  link              name
0       www.google.com  Article 1 series
1        www.yahoo.com         Article 2
2         www.bing.com  Article 3 series
3  www.google.com/test  Article 1 series
4   www.duckduckgo.com         Article 4

merged_df = df.groupby("link").first()

OUTPUT:
                    description              name
link                                             
www.bing.com               cccc  Article 3 series
www.google.com              aaa  Article 1 series
www.google.com/test         aaa  Article 1 series
www.yahoo.com               bbb         Article 2

 data = []
 for index, row in df.iterrows():
    data_dict = {}
    data_dict["link"] = index
    data_dict["description"] = row.description
    data_dict["name"] = row.name
    data.append(data_dict)

OUTPUT of data: 
[{'description': 'cccc', 'link': 'www.bing.com', 'name': 'www.bing.com'},
 {'description': 'aaa', 'link': 'www.google.com', 'name': 'www.google.com'},
 {'description': 'aaa', 'link': 'www.google.com/test', 'name': 'www.google.com/test'},
 {'description': 'bbb', 'link': 'www.yahoo.com', 'name': 'www.yahoo.com'}]

0 голосов
/ 29 марта 2019

В коде, который вы пробовали, у вас есть только один недостаток, который не дает вам требуемого результата.

listOne.append (listTwo [0] [ "ссылка"])

Вы добавляете значение ссылки к listOne .

Или другими словами, вы добавляете www.google.com к listOne. Принимая во внимание, что вы хотите, чтобы они были как пара ключ-значение в listOne[i].

Следовательно, ваш результат показывает следующие виды:

[{'name': 'Article 1 series', 'description': 'aaa'}, {'name': 'Article 2', 'description': 'bbb'}, {'name': 'Article 1 серия ',' description ':' abb '}, {' name ':' Article 3 series ',' description ':' cccc '},' www.google.com ',' www.google.com ',' www.yahoo.com ',' www.bing.com ',' www.google.com/test ',' www.google.com/test']

Как ясно видно выше, ваша ссылка добавляется к listOne .

Однако, если вы добавите пару ключ-значение в словарь (в вашем случае listOne[i]), ваш код будет работать отлично. (Ключ 'link' и значение listTwo [i] ['link'] )

Вот исправленный код:

listOne = [{'name': 'Article 1 series', 'description': 'aaa'},
           {'name': 'Article 2', 'description': 'bbb'},
           {'name': 'Article 1 series', 'description': 'abb'},
           {'name': 'Article 3 series', 'description': 'cccc'}]

listTwo = [{'name': 'Article 1 series', 'link': 'www.google.com'},
           {'name': 'Article 2', 'link': 'www.yahoo.com'},
           {'name': 'Article 3 series', 'link': 'www.bing.com'},
           {'name': 'Article 1 series', 'link': 'www.google.com/test'},
           {'name': 'Article 4', 'link': 'www.duckduckgo.com'}]


while listTwo:
    for i in range(len(listOne)):
        if i >= len(listTwo):
            break
        if not 'link' in listOne[i].keys():
            if listOne[i]['name'] == listTwo[i]['name']:
                print('found')
                listOne[i]['link'] = listTwo[i]['link']
            else:
                continue
        else:
            continue

    listTwo.pop(0)
0 голосов
/ 29 марта 2019

Из того, что я понимаю, вы можете просто сделать это:

>>> merged =[{**one, **two} for one, two in zip(listOne, listTwo)]
>>> print(merged)
[
   {'name': 'Article 1 series', 'description': 'aaa', 'link': 'www.google.com'},
   {'name': 'Article 2', 'description': 'bbb', 'link': 'www.yahoo.com'}, 
   ...
]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...