从列表列表中删除重复的列表项

时间:2017-04-13 22:03:13

标签: python list python-3.x

我有一份列表清单如下:

All_Data= [[['Chemical Name', 'Average Ret. Time', 'Maximum Area'],
 ['1-hexanol', 5.10, 2544937.0], ['1-hexanol', 8.69, 3798101.0],
 ['1-hexanol', 5.54, 2470679.0], ['2-propanone-1-hydroxy-', 1.97, 227607.0], 
 ['acetic acid', 1.962, 227607.0], ['acetic acid', 1.75, 38359423.0], 
 ['acetoin', 2.32, 478054.0]],
[['Chemical Name', 'Average Ret. Time', 'Maximum Area'], ['1-pentanol', 3.00, 24864.0], 
 ['2-heptanone', 5.54, 10027158.0], ['2-pentanone', 2.10, 858204.0], 
 ['2-pentanone', 2.03, 858204.0], ['2-pentanone', 2.037, 858204.0], 
 ['2-pentanone', 1.97, 858204.0], ['pentane, 2,3,3-trimethyl-', 2.84, 1775913.0], 
 ['pentane, 2,3,4-trimethyl-', 2.75, 807020.0]],
[['Chemical Name', 'Average Ret. Time', 'Maximum Area'], ['.alpha.-pinene', 7.00, 8190.0], 
 ['.alpha.-pinene', 8.729, 21582890.0], ['ethyl hexanoate', 9.47, 71863418.0], 
 ['nonanal', 13.93, 10301295.0], ['pentanoic acid, ethyl ester', 5.88, 19659678.0],
 ['propanoic acid, ethyl ester', 2.30, 8107638.0]]]

因此该列表包含3个级别:列表中有三个主要子列表名为“All_Data”,每个子列表包含更多子列表中的一组数据。 我想独立地比较三个主要子列表中的子列表,看看两个子列表中的第一项是否匹配,我想删除一个子列表并保留一个。例如,在第一个数据中,“1-己醇”重复三次,我想只保留一个子列表:

['1-hexanol', 5.10, 2544937.0]

并删除其他两个:

['1-hexanol', 8.69, 3798101.0], ['1-hexanol', 5.54, 2470679.0]

我尝试了以下代码,但它给出了错误:“TypeError:'int'对象不可订阅”。

代码:

for i in All_Data:
    for j in range(0, len(i)):
        for k in range(1, len(i)):
            if i[j[0]] == i[k[0]]:
                del i[k[0]]

请帮我解决这个问题。

亲切的问候, 阿里

2 个答案:

答案 0 :(得分:1)

错误消息告诉您问题:您不能下标整数。 j k 是整数。

if i[j[0]] == i[k[0]]:

也许您打算将它们用作2D表达式中的第一个索引:

if i[j][0] == i[k][0]:

根据OP的评论更新(第二个问题):

啊,是的 - 这是一个老问题:当你还在踩着它时,你缩短了一个列表。代码无法按您的方式工作:每次删除行时,都会更改后面行的索引。首先,你错过了一排;第二,你的循环试图运行原始行数。

例如,从10行开始,行3,4和6(0 - 9)与第1行具有相同的第一个元素。在j = 0时,从0到9运行k

当k达到3时,您会找到副本。删除第3行并移至第4行...除了原始第4行现在是第3行,而您现在正在查看的行是原始第5行。到第6行,并删除那个一个。你继续第7行,传递它,然后第8行......

除了列表中没有剩下第8行。您的循环取决于运行9的生成器:在您更改列表时不会更改。 k 现已超出范围。

<强> REPAIR 一般的解决方案是标记行,以便以后删除它们。当您离开主标记循环时,再次传递以删除标记为删除的任何内容。同样,请注意不要跳过行:要么向后工作,要么使用 while 循环,只有在保持行时才增加索引。

答案 1 :(得分:0)

虽然@Prune已经提供了有关代码中错误的详细说明,但我想为您的问题提供替代解决方案。

基本上,您可以为第二级数组定义函数remove_duplicate,以根据第一个元素删除第三级数组,然后使用list comprehensive生成最终结果:

def remove_duplicate(sublist):    
    seen = set()
    return [e for e in sublist if not (e[0] in seen or seen.add(e[0]))]

result = [remove_duplicate(sublist) for sublist in All_Data]