如何遍历两个列表字典,以将唯一键值附加到一个列表字典,并通过共享重复值条目继续执行其他字典?

时间:2019-03-29 03:53:40

标签: python python-3.x list loops dictionary

我在弄清楚如何将唯一键值从一个列表字典合并到另一个字典中具有重复值的列表字典时遇到麻烦。

这两个列表字典是从不同的来源生成的,这些来源具有一些​​重复的“名称”值,并且并不总是遵循相同的索引。因此,有时一组相关的键值会出现在其索引更远(或可能更早)的一个列表中。另外,两个列表字典的长度可能不相同,其中一个包含的条目要多于另一个。

我已经尝试了一些嵌套循环,但是我似乎无法弄清楚如何处理同时索引并为尚未匹配的整体重新启动循环。由于列表字典的范围不匹配,最后我也会收到错误消息。

这是我尝试过的:

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)

最终,当“名称”键值匹配时,我想将“链接”键值合并到相应的找到的listOne索引中。否则,寻找上一个不匹配或下一个匹配的“名称”键值。如果listOne中不存在“名称”键值,或者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 :(得分:0)

据我了解,您可以简单地做到这一点:

>>> 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'}, 
   ...
]

答案 1 :(得分:0)

如果列表很大,请开始使用熊猫

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

答案 2 :(得分:0)

在您尝试过的代码中,您只有一个缺陷,无法提供所需的结果。

  

listOne.append(listTwo [0] [“ link”])

您要将链接附加到 listOne

或者换句话说,您要将www.google.com附加到listOne。而您希望它们在listOne[i]中作为键值对。

因此,您的结果显示如下:

  

[{'name':'Article 1 series','description':'aaa'},{'name':'Article 2','description':'bbb'},{'name':'Article 1系列”,“说明”:“ abb”},{“名称”:“第3条系列”,“说明”:“ cccc”},“ www.google.com”,“ www.google.com”,“ www.yahoo.com”,“ www.bing.com”,“ www.google.com/test”,“ www.google.com/test”]

从上面可以清楚地看到,您的 link 链接将附加到 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)