【问题标题】:Reordering duplicate contacts. Problems with lists重新排序重复的联系人。列表问题
【发布时间】:2026-01-07 15:15:01
【问题描述】:

我以以下方式获得了一个包含 120000 行的 csv:

ID Duplicate
1 65
2 67
4 12
4 53
4 101
12 4
12 53
101 ...

这个列表基本上指定了一些用户 ID,以及与该用户重复的用户。现在列表是如何组成的,我无法在 Excel 中真正过滤掉它,因此我试图用这个结果来转换列表:

[1, 65]
[2, 67]
[4, 12, 53, 101]

之后,我将能够写入一个新的 csv,仅删除每个元素的 list[0],这样我就可以为每个“重复用户块”保留一个用户。然后在 Excel 中删除所有剩余的用户 ID。

但是到了这一点我遇到了一些问题:

import csv

with open("contacts.csv", "rt") as f:
    reader = csv.reader(f, delimiter="\t")

    contacts = []
    for row in reader:
        if row[0] not in contacts:
            contacts.append(row[0])
        if row[1] not in contacts:
            position = contacts.index(row[0])
            contacts[position].append(row[1])

当然,我收到错误“AttributeError: 'str' object has no attribute 'append'”,因为 contacts[position] 是一个字符串。但是如何更改代码,以便获得每个重复联系人块的列表?

谢谢!

【问题讨论】:

  • 为什么 101 在输出中没有跟随 53 ??
  • 第一列排序了吗?
  • 你是对的,编辑它。是的,第一列已排序

标签: python list csv


【解决方案1】:

标准python中也有几乎一个衬里

import csv
from itertools import groupby

with open("contacts.csv", "rt") as f:
    reader = csv.reader(f, delimiter="\t")
    contacts = [[k] + [r[1] for r in g] for k, g in groupby(reader, key=lambda row: row[0])]

我也喜欢 pandas 的解决方案,但这意味着要学习一个新的 api。

【讨论】:

  • 谢谢!遇到与之前解决方案相同的问题。最终目标是从每个“重复用户块”中保留一个用户。例如,在您的解决方案的输出中,我得到 ['3001464', '3001465'], ['3001465', '3001464'] (真实文件!)。如果我从每个列表中删除第一个元素以仅获取重复的元素,这将不起作用;)有什么想法吗?在我上面给出的列表中: [1, 65] [2, 67] [4, 12, 53, 101] 我想删除 1, 2 和 4,所以我可以告诉 Excel 过滤所有用户 65, 67, 12、53 和 101,从而保留一个原始用户,而不是重复用户。
  • @user2252633 您正在寻找图的连接组件。有一些关于此的主题,例如 *.com/questions/10301000/… 。您还可以使用内置函数的外部库,例如 networkx 或 igraph。
【解决方案2】:

即使您的 csv 文件未排序并且缺少一些条目,这也将起作用:

with open('contacts.csv') as infile:
    data = {}
    for i,dup in csv.reader(infile):
        if i not in data:
            if dup in data:
                data[i] = data[dup]
                continue

            data[i] = set((i, dup))
            data[dup] = data[i]
            continue

        data[i].add(dup)

for _,dups in data.items():
    print(sorted(dups))

更新:如果您想避免打印多组重复:

for k,dups in list(data.items()):
    if k not in data: continue
    print(sorted(dups))
    for d in dups: data.pop(d)

【讨论】:

  • 我收到此错误:回溯(最近一次调用最后一次):文件“duplicate.py”,第 5 行,在 for i,dup in csv.reader(infile): ValueError: not足够的值来解压(预期 2,得到 1)可能与 CSV 文件有关。我在一行的两个值之间有一个空格,然后是一个新行。任何指针?
  • @user2252633:这似乎是文件末尾的空行导致的错误。删除应该可以解决它。或者,如果您的 csv 文件在某个时候停止以逗号分隔,那么这也可能导致此错误
  • 嗯,还是不行,你说的两个都试过了。我还以不同的方式保存了 csv,所以我在每个号码之间都有一个逗号: Contact No_,Duplicate Contact No_ 1000004,1000588 1000009,1000489 1000009,1000531 1000009,1000643 现在我得到:Traceback(最近一次通话最后一次):文件“ duplicate.py",第 17 行,在 中用于 _,dups in data: ValueError: too many values to unpack (expected 2)
  • @user2252633:对不起,这是我的一个愚蠢的错误。现在已经修复了
  • 感谢您的帮助,但遗憾的是,这不是我需要的输出。我希望在一个列表中所有彼此重复的用户。然后这些用户将永远无法再次出现在另一个列表中,否则我无法从每个块中删除一个原始用户,然后再删除所有其他用户..