从引用列表中过滤多个列表

时间:2018-02-20 16:17:13

标签: python python-2.7 list

我有4个大约150M行的列表,我需要通过列表1上的重复来过滤它们。

lst1=['1','2','1','3']
lst2=['a','b','c','d']
lst3=['a','b','c','d']
lst4=['a','b','c','d']

给我这个神奇的代码:

lst1=['1','2','3']
lst2=['a','b','d']
lst3=['a','b','d']
lst4=['a','b','d']

我试图:

    set1=list(set(list1))
    newlst2=[]
    newlst3=[]
    newlst4=[]
    for i in set1:
        newlst2.append(lst2[lst1.index(i)])
        newlst3.append(lst3[lst1.index(i)])
        newlst4.append(lst4[lst1.index(i)])

问题是由于我使用的巨大列表,这需要永远。 有没有办法优化这个?

我为古老的编码方式道歉,但我是生命科学家:)

编辑澄清:列表不是独立的,lst1 [1],lst2 [1],lst3 [1],lst4 [1]是同一“事物”的4个测量值。 lst1是一个必须只出现一次的唯一标识符,因此需要删除重复项并将该删除扩展到其他列表。 即:从lst1中删除1(因为它是重复的)应该导致从lst2,lst3和lst4中删除“c”,因为它们处于相同的位置。 lst1 [3]是重复的 - >所以lst1 [3],lst2 [3],lst3 [3]和lst [4]被删除。

选择Chris_Rands回答:

from collections import OrderedDict
from operator import itemgetter

def filter_lists(master_lst, lst2, lst3, lst4):
    unique = list(OrderedDict.fromkeys(master_lst))
    unique_idx = [master_lst.index(item) for item in unique]
    for lst in (master_lst, lst2, lst3, lst4):
        yield list(itemgetter(*unique_idx)(lst))

lst1=['1','2','1','3']
lst2=['a','b','c','d']
lst3=['a','b','c','d']
lst4=['a','b','c','d']

print(list(filter_lists(lst1, lst2, lst3, lst4)))
# [['1', '2', '3'], ['a', 'b', 'd'], ['a', 'b', 'd'], ['a', 'b', 'd']]

该过程的缓慢部分仍然是针对master_lst索引唯一的唯一元素。由于OrderedDict返回保留列表的初始顺序,我使用它而不是索引:

unique_idx = []
total_counts=len(unique)
master_count=0
unique_count=0

while total_counts>0:
    if unique[unique_count]==master_lst[master_count]:
        unique_idx.append(master_count)
        unique_count=unique_count+1
        total_counts=total_counts-1
    master_count=master_count+1
它似乎更快。 哇,创建unique_idx从几个小时到几秒钟!

1 个答案:

答案 0 :(得分:4)

一种方法是使用OrderedDict.fromkeys()唯一的列表(同时保留订单),然后使用list.index获取唯一索引,然后简单地遍历所有list并提取唯一索引使用itemgetter()

from collections import OrderedDict
from operator import itemgetter

def filter_lists(master_lst, lst2, lst3, lst4):
    unique = list(OrderedDict.fromkeys(master_lst))
    unique_idx = [master_lst.index(item) for item in unique]
    for lst in (master_lst, lst2, lst3, lst4):
        yield list(itemgetter(*unique_idx)(lst))

lst1=['1','2','1','3']
lst2=['a','b','c','d']
lst3=['a','b','c','d']
lst4=['a','b','c','d']

print(list(filter_lists(lst1, lst2, lst3, lst4)))
# [['1', '2', '3'], ['a', 'b', 'd'], ['a', 'b', 'd'], ['a', 'b', 'd']]