Python - 如何在地址列表中查找和合并重复项(列表本身)

时间:2017-01-10 19:03:11

标签: python list merge duplicates

我有一个从网站上删除的地址列表,我想将它与之前的scrape中的地址列表进行比较以合并并删除重复项。我删除的列表有邮政编码,有时是城市,而以前的清单只有城市,没有拉链。我的最终目标是合并所有重复项并保留条目而不重复。

以下是我想要合并的2个条目的示例:

['2 DUDES RC HOBBIES', 'SALT LAKE CITY', 'UT', '84106', '(801) 849-0292']

['2 DUDES RC HOBBIES', 'SALT LAKE CITY', 'UT', '', '(801) 849-0292']

这是另一个片段:

['1 STOP HOBBY & CRAFT SHOP', 'BATH', 'NY', '', '(607) 776-9293']

['1/32 SLOTCAR RACEWAY', 'UNIVERSITY PLACE', 'WA', '', '(253) 255-1807']

['2 DUDES RC HOBBIES', 'SALT LAKE CITY', 'UT', '84106', '(801) 849-0292']

['2 DUDES RC HOBBIES', 'SALT LAKE CITY', 'UT', '', '(801) 849-0292']

['2 JACKS HOBBIES AND MORE', 'LAFAYETTE', 'LA', '70507', '(337) 212-2916']

['2 JACKS HOBBIES AND MORE', 'LAFAYETTE', 'LA', '', '(337) 212-2916']

['3D HOBBIES', 'SOCIAL CIRCLE', 'GA', '', '(678) 283-9662']

['3DXHOBBIES', 'GREEN BROOK', 'NJ', '', '(732) 424-6400']

['5TH GEAR POWERSPORTS', 'ELKO', 'NV', '89801', '(775) 777-3373']

['5TH GEAR POWERSPORTS', 'ELKO', 'NV', '', '(775) 777-3373']

第1和第2条应保留,而第3和第4条应合并

编辑:

如果我不清楚,我很抱歉,这是我第一次发帖提问,我还有很多需要学习的地方。我会尝试更好地解释我的问题。

我有两个包含商店列表的CSV文件。两个文件都有相同的字段;姓名,城市,州,邮编,电话。一个文件在ZIP列中有数据而另一个文件没有。目标是最终得到一个CSV文件,该文件包含具有邮政编码的文件所独有的商店。

without_zips = []
with open('without_zips.csv', newline='') as f:
    reader = csv.reader(f)
    for row in reader:
        without_zips.append(row)

with_zips = []
with open('with_zips.csv', newline='') as f:
    reader = csv.reader(f)
    for row in reader:
        with_zips.append(row)

使用@kzimmerman方法建议有效,但我用without_zips切换了with_zips的每个实例。以下代码有效:

for without_zip_entry in without_zips:
    this_telephone = without_zip_entry[-1]
    for i, zip_entry in enumerate(with_zips):
        that_telephone = zip_entry[-1]
        if this_telephone in that_telephone:
            # Remove duplicate without zip code
            del with_zips[i]

2 个答案:

答案 0 :(得分:1)

嗯,这个答案不是以pythonic的方式,但至少它应该让你知道下一步该去哪里。

a = ['1 STOP HOBBY & CRAFT SHOP', 'BATH', 'NY', '', '(607) 776-9293']
a1 = ['1/32 SLOTCAR RACEWAY', 'UNIVERSITY PLACE', 'WA', '', '(253) 255-1807']
a2 = ['2 DUDES RC HOBBIES', 'SALT LAKE CITY', 'UT', '84106', '(801) 849-0292']
a3 = ['2 DUDES RC HOBBIES', 'SALT LAKE CITY', 'UT', '', '(801) 849-0292']
a4 = ['2 JACKS HOBBIES AND MORE', 'LAFAYETTE', 'LA', '70507', '(337) 212-2916']
a5 = ['2 JACKS HOBBIES AND MORE', 'LAFAYETTE', 'LA', '', '(337) 212-2916']
a6 = ['3D HOBBIES', 'SOCIAL CIRCLE', 'GA', '', '(678) 283-9662']
a7 = ['3DXHOBBIES', 'GREEN BROOK', 'NJ', '', '(732) 424-6400']
a8 = ['5TH GEAR POWERSPORTS', 'ELKO', 'NV', '89801', '(775) 777-3373']
a9 = ['5TH GEAR POWERSPORTS', 'ELKO', 'NV', '', '(775) 777-3373']

data = [a, a1, a2, a3, a4, a5, a6, a7, a8, a9]

result = dict()

for item in data:
    key = item[0]
    if key in result.keys():
        # merge them here
        if item[4]:
            result[key][4] = item[4]
        continue

    result[key] = item

for item in result.values():
    print item

以下是您必须做的事情:   - 在每个列表中定义唯一键。你应该知道这个列表。如果你想使用它们中的多个 - 它仍然可能,但更难。如果你这样做,请阅读#better-options部分。   - 定义如何合并它们。什么数据被认为是有效的。   - 删除无效数据或在其他结构中存储有效的和合并的数据。

更好的选择

选项1。

您可能不希望以我上面描述的方式执行此操作,就好像您有数百万行,最好将它们保存到数据库中。 SQLite将是一个不错的选择。算法大部分是相同的,可能需要更长的时间,但数据将是持久的,如果代码中发生某些事情或临时内存,您将不会松开它。

选项2。

如果您正在尝试执行与数据科学相关的任何事情,您可能正在使用pandas,这种方法可以通过字段对DataFrame进行分组。

它能回答你的问题吗?

答案 1 :(得分:0)

如果您可以合理地假设电话号码应该是唯一的(我们通常不能依赖姓名,城市,州和邮政编码是唯一的),那么以下内容可能是您的解决方案。不幸的是,以下解决方案可能会有很长的运行时间,具体取决于列表的大小(O(n ^ 2))。

without_zips = [['1 STOP HOBBY & CRAFT SHOP', 'BATH', 'NY', '', '(607) 776-9293'],
                ['1/32 SLOTCAR RACEWAY', 'UNIVERSITY PLACE', 'WA', '', '(253) 255-1807'],
                ['2 DUDES RC HOBBIES', 'SALT LAKE CITY', 'UT', '', '(801) 849-0292'],
                ['2 JACKS HOBBIES AND MORE', 'LAFAYETTE', 'LA', '', '(337) 212-2916'],
                ['3D HOBBIES', 'SOCIAL CIRCLE', 'GA', '', '(678) 283-9662'],
                ['3DXHOBBIES', 'GREEN BROOK', 'NJ', '', '(732) 424-6400'],
                ['5TH GEAR POWERSPORTS', 'ELKO', 'NV', '', '(775) 777-3373']]


with_zips =   [['2 DUDES RC HOBBIES', 'SALT LAKE CITY', 'UT', '84106', '(801) 849-0292'],
               ['2 JACKS HOBBIES AND MORE', 'LAFAYETTE', 'LA', '70507', '(337) 212-2916'],
               ['5TH GEAR POWERSPORTS', 'ELKO', 'NV', '89801', '(775) 777-3373']]



for with_zip_entry in with_zips:
    this_telephone = with_zip_entry[-1]
    for i, no_zip_entry in enumerate(without_zips):
        that_telephone = no_zip_entry[-1]
        if this_telephone in that_telephone:
            # Remove duplicate without zip code
            del without_zips[i]


print(without_zips+with_zips)