Python在for循环中减少了一个大的速度列表

时间:2018-02-02 22:26:44

标签: python list for-loop recursion

我试图获取400万个条目的列表,而不是迭代它们全部,减少for循环中列出的列表。

在循环中找到缩减标准。一些后来的my_huge_list元素包含2个连续元素的组合,允许它们立即被丢弃。

我将从my_huge_list中删除包含1,2和A,B的子列表。

请注意我事先并不知道1,2和A,B是非法的,直到我进入我的for循环。

output_list = []

my_huge_list = [[0,1,2,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,3,4],[0,1,2,4],[0,1,2,3,4],[A,B],[0,1,3,A,B],[0,1,2,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,3,4],[0,1,2,4]...] #to 4m assorted entries

for sublist in my_huge_list[:]: 
   pair = None
   for item_index in sublist[:-1]: #Edit for Barmar.  each item in sublist is actually an object with attributes about allowed neighbors.
     if sublist[item_index +1] in sublist[item_index].attributes['excludes_neighbors_list']:
        pair = [sublist[item_index],sublist[item_index +1]]  #TODO build a list of pairs

   if pair != None: #Don't want pair in any item of output_list
      my_huge_list = [x for x in my_huge_list if not ','.join(pair) in str(x)]  #This list comprehension sole function to reduce my_huge_list from 4m item list to 1.7m items

  #if '1, 2' in str(sublist): #Don't want 1,2 in any item of output_list
        #my_huge_list = [x for x in my_huge_list if not '1, 2' in str(x)]  #This list comprehension sole function to reduce my_huge_list

  #elif 'A, B' in str(sublist): #Don't want A,B in any item of output_list
        #my_huge_list = [x for x in my_huge_list if not 'A, B' in str(x)]  #This list comprehension sole function to reduce my_huge_list from 1.7m item list to 1.1m items


  else:
     output_list.append(sublist) 


my_huge_list
>>>[[0,1,3,4],[0,1,3,4],[0,1,3,4],[0,1,3,4]...] 

所以' for循环'遗憾的是,似乎没有更快,因为my_huge_list仍在所有4m条目上迭代,即使它被列表理解迅速减少了。

[my_huge_list不需要按任何顺序处理,在此循环后不需要保留。]

[我考虑过将for循环变成一个子函数并使用map和浅拷贝,但不能把这个架构弄清楚。]

[我确定通过测试按列表理解删除列表元素比强制执行所有4m子列表更快。]

谢谢!

2 个答案:

答案 0 :(得分:1)

我在这里挖掘它:

my_huge_list = [[0,1,2,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,3,4],[0,1,2,4],[0,1,2,3,4],['A','B'],[0,1,3,'A','B'],[0,'A','B'],[0,1,2,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,3,4],[0,1,2,4]] #to 4m assorted entries

# ... do whatever and return unwanted list... #

# ... if needed, convert the returned items into lists before putting into unwanted ... #

unwanted = [[1,2], ['A','B']]

index = 0
while index < len(my_huge_list):
    sublist = my_huge_list[index]
    next = True
    for u in unwanted:
        if u in [sublist[j:j+len(u)] for j in range(len(sublist)-len(u)+1)] or u == sublist:
            my_huge_list.pop(index)
            next = False
    index += next

print(my_huge_list)

# [[0, 1, 3, 4], [0, 1, 3, 4], [0, 1, 3, 4], [0, 1, 3, 4]]

它并不优雅,但它完成了工作。一个巨大的警告是,在迭代它时修改list是不好的业力(专业人员可能会对我摇头),但处理4密耳的大小你可以理解我试图保存一些记忆通过适当的修改。

这也是可扩展的,因此如果您有多个不同大小的unwanted数字,它仍然应该从您的巨大列表中捕获它。如果元素大小为1,请尝试匹配my_huge_list中的预期元素类型。例如如果您的my_huge_list有[1],那么您的不受欢迎也应该是[1]。如果元素是string而不是list,则您string中需要unwanted。但是,int / float会破坏当前代码,因为您无法对其进行迭代,但您可以在迭代不需要的内容之前添加额外的处理。

答案 1 :(得分:0)

您在主def sublist_contains(l, pair): for i in range(len(l)-1): if l[i] == pair[0] and l[i+1] == pair[1]: return True return False output_list = [sublist for sublist in my_huge_list if not(list_contains(sublist, ['A', 'B']) or list_contains(sublist, ['1', '2']))] 循环中重复遍历您的巨大列表两次,然后每次找到无效元素时,您在列表推导中再次迭代它以删除所有这些无效元件。

最好只使用列表推导将这些元素从列表中过滤掉一次。

sublist_contains()

我的keytool -genkeypair -keyalg EC -keysize 256 -sigalg SHA256withECDSA函数假定它总是只需要测试的行中的两个元素。如有必要,您可以使用更通用的功能替换它。见elegant find sub-list in list