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

Python在for循环中减少了大量的速度列表,python,list,for-loop,recursion,Python,List,For Loop,Recursion,我试图获取一个包含400万个条目的列表,而不是遍历所有条目,减少for循环中的列表,该循环在进行时对它们进行枚举 在循环中可以找到缩减标准。后来的一些my_大型列表元素包含两个连续元素的组合,允许立即丢弃它们 在这里,我将从我的列表中删除包含1,2和A,B的子列表 请注意,在我进入for循环之前,我不知道1,2和A,B是非法的 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,

我试图获取一个包含400万个条目的列表,而不是遍历所有条目,减少for循环中的列表,该循环在进行时对它们进行枚举

在循环中可以找到缩减标准。后来的一些my_大型列表元素包含两个连续元素的组合,允许立即丢弃它们

在这里,我将从我的列表中删除包含1,2和A,B的子列表

请注意,在我进入for循环之前,我不知道1,2和A,B是非法的

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循环”似乎没有变得更快,因为我的庞大列表仍然在所有4百万个条目上迭代,尽管列表理解很快就减少了

[我的清单不需要按任何顺序处理,也不需要在此循环后保留。]

[我考虑过将for循环变成一个子函数,并使用map和浅层副本,但无法理解此架构。]

[通过测试,我确信通过列表理解删除列表元素比暴力强制所有4m子列表要快。]


谢谢

您将在庞大的列表上迭代两次,一次在主
for
循环中,然后每次发现无效元素时,您将在列表理解中再次迭代该元素,以删除所有这些无效元素

最好是通过列表理解将这些元素从列表中过滤一次

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']))]
我的
子列表\u contains()
函数假定一行中始终只有两个元素需要测试。如有必要,可以使用更通用的函数替换此函数。请看

以下是我的挖掘:

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]]
my_Hugh_list=[0,1,2,3,4]、[0,1,3,4]、[0,1,3,4]、[0,1,3,4]、[0,1,2,4]、[0,1,2,3,4]、[0,1,3]、[A]、[B]、[0,1,3]、[0,1,2,4]、[0,1,3,4]、[0,1,2,3,4]、[0,1,3]、[0,4]、[0,1,3,4]、[0,4]、[0,1,1,3,4]、[4]、[1,4]、[4]、[1,4]、[4]、[4]、[4]、[4]、[4]、[4]、[4
# ... 做任何事并返回不需要的列表#
# ... 如果需要,将返回的项目转换为列表,然后再放入不需要的#
不需要的=[[1,2],'A','B']]
索引=0
而索引
这并不优雅,但它完成了任务。一个巨大的警告是,在迭代过程中修改
列表
是一个坏的因果报应(专业人士可能会对我摇头),但处理4 mil大小的问题时,你可以理解我试图通过就地修改来节省一些内存


这也是可缩放的,因此如果您有多个不同大小的
不需要的
,它仍然可以从庞大的列表中捕获它。如果元素大小为1,请尝试匹配
我的列表中的预期元素类型。e、 g.如果你的
my\u庞大的\u列表中有[1],那么你不想要的也应该是[1]。如果元素是
字符串
而不是
列表
,则在
中需要该
字符串
int
/
float
将破坏当前代码,因为您无法对其进行迭代,但您可以在迭代不需要的代码之前添加额外的处理。

将子列表转换为字符串,然后搜索它们是昂贵的。400万是一件大事,我不确定这在您的项目环境中是否可行,但您是否考虑过在数据库中使用SQL而不是在程序的内存中使用列表?@Barmar是的,对不起,我没有进行str转换。它实际上是对numpy数组值的逻辑测试,我使用了str(x)为了简化帖子。@Alexis.Rolland我可以如何安排SQL以使此例程更快?@Joylove如果我理解正确,您只想过滤掉子列表[1,2]和[A,B]。假设将数据加载到一个表中,其中每个子列表存储在一条记录中。您可以简单地执行以下操作:从表中选择子列表,其中子列表不在(“[1,2]”,“[A,B]”)我认为这需要我通过(配对),为此,我需要检查我的庞大列表中的所有子列表,以发现不需要的配对1,2和A,B。我理解对了吗?我不理解这个问题
pair
正在调用
list_contains(sublist,['A',B'])或list_contains(sublist,['1',2'])中传递。
这个问题有两个部分,第一个1,2和A,B无效,因此我无法将列表理解为output_list,直到1,2和A,B都被排除,否则output_list可能包含1,2或A的实例,B.第二,为了实际识别1,2和A,B作为一对传递,我需要在所有4M子列表上迭代,作为A,B只能在最后一个列表索引中找到一次。列表理解返回所有子列表,其中没有
1,2
A,B
。您没有看到列表理解中的
if
?这使它成为一个过滤器。谢谢,现在尝试一个while循环。最终我的列表和输出列表的长度相同,所以为了代码的可读性,我使用了这个比较。这正在起作用。谢谢关于在迭代过程中修改列表,根据文档,my_Hugh_list[:]中的for子列表正在使用完整切片处理浅拷贝。在迭代时不修改同一个列表有很多很好的理由,请参见此处:浅表副本可以工作(基本上是列表理解),但在您的用例中,创建最多4mil条目的浅表副本似乎毫无意义。