根据每个子列表中的第三个项目删除列表列表中的重复项

时间:2014-06-18 21:49:52

标签: python duplicate-removal nested-lists

我有一个列表如下:

c = [['470', '4189.0', 'asdfgw', 'fds'],
     ['470', '4189.0', 'qwer', 'fds'],
     ['470', '4189.0', 'qwer', 'dsfs fdv'] 
      ...]

c有大约30,000个内部列表。我想做的是根据每个内部列表中的第4项消除重复项。所以上面的列表列表如下:

c = [['470', '4189.0', 'asdfgw', 'fds'],['470', '4189.0', 'qwer', 'dsfs fdv'] ...]

这是我到目前为止所做的:

d = [] #list that will contain condensed c
d.append(c[0]) #append first element, so I can compare lists
for bact in c: #c is my list of lists with 30,000 interior list
    for items in d:
        if bact[3] != items[3]:
            d.append(bact)  

我认为这应该可行,但它只是运行和运行。我让它运行30分钟,然后杀了它。我不认为该程序需要这么长时间,所以我猜测我的逻辑有问题。

我觉得创建一个全新的列表列表非常愚蠢。任何帮助将不胜感激,请随时挑剔,因为我正在学习。如果不正确,请更正我的词汇。

3 个答案:

答案 0 :(得分:5)

我会这样做:

seen = set()
cond = [x for x in c if x[3] not in seen and not seen.add(x[3])]

说明:

seen是一个跟踪已经遇到的每个子列表的第四个元素的集合。 cond是精简列表。如果x[3](其中xc中的子列表)不在seen中,x将添加到cond和{{} 1}}将添加到x[3]

seen将返回seen.add(x[3]),因此None始终为not seen.add(x[3]),但只有在Truex[3] not in seen时才评估该部分因为Python使用短路评估。如果评估了第二个条件,它将始终返回True并产生将True添加到x[3]的副作用。这是发生了什么的另一个例子(seen返回print并且具有打印内容的“副作用”):

None

答案 1 :(得分:1)

您当前的代码中存在重大的逻辑缺陷:

for items in d:
    if bact[3] != items[3]:
        d.append(bact)  

这会为bact中与匹配的每个项目d 添加一次d。要获得最小的修复,您需要切换到:

for items in d:
    if bact[3] == items[3]:
        break
else:
    d.append(bact)  
如果bact中的所有项目都不匹配,请

添加d一次。我怀疑这意味着你的代码会在更合理的时间内运行。


最重要的是,一个显而易见的性能改进(速度提升,尽管以内存使用为代价)将保留到目前为止您已经看到的set个第四个元素。集合上的查找使用哈希值,因此成员资格测试(突出显示)将更快。

d = []
seen = set()
for bact in c:
    if bact[3] not in seen: # membership test
        seen.add(bact[3])
        d.append(bact)

答案 2 :(得分:0)

使用熊猫。我假设你有更好的列名。

c = [['470', '4189.0', 'asdfgw', 'fds'],
     ['470', '4189.0', 'qwer', 'fds'],
     ['470', '4189.0', 'qwer', 'dsfs fdv']]
import pandas as pd
df = pd.DataFrame(c, columns=['col_1', 'col_2', 'col_3', 'col_4'])
df.drop_duplicates('col_4', inplace=True)
print df

  col_1   col_2   col_3     col_4
0   470  4189.0  asdfgw       fds
2   470  4189.0    qwer  dsfs fdv