我有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从几个小时到几秒钟!
答案 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']]