Skip to main content
 首页 » 编程设计

python之从 python 中不匹配条件的列表中提取元素的最快方法

2025年05月04日10zhoujg

我正在寻找最快的方法,以根据条件从列表中提取所有元组成员。

例子: 从元组列表(例如 [(0,0,4),(1,0,3),(1,2,1),(4,0,0)])我需要提取所有具有更多的成员在第一个元组位置超过 3,然后在第二个元组位置超过 2,然后在最后一个元组位置超过 1。 在这个例子中应该提取(4,0,0)(->第一个条件),什么都不提取(->第二个条件)和(0,0,4),(1,0,3)(->最后一个条件)。这个例子很小,我需要在数千个元组的列表上执行。

根据我根据您的回答生成的代码,以下是秒内的结果:

my_naive1,就像 Emil Vikström 提出的那样? 13.0360000134

我的天真2 110.727999926

蒂姆·皮茨克 9.8329999446

唐 12.5640001297

import itertools, operator, time, copy 
from operator import itemgetter 
 
 
def combinations_with_replacement_counts(n, r):  #(A, N) in our example.N individuals/balls in A genotypes/boxes 
   size = n + r - 1 
   for indices in itertools.combinations(range(size), n-1): 
       #print indices 
       starts = [0] + [index+1 for index in indices] 
       stops = indices + (size,) 
       yield tuple(map(operator.sub, stops, starts)) 
 
 
xp = list(combinations_with_replacement_counts(3,20))  # a very small case 
 
a1=time.time() 
temp=[] 
for n in xp: 
    for n1 in xp: 
 
        for i in xp: 
            if i[0] <= min(n1[0],n[0]) or i[1] <= min(n1[1],n[1]) or i[2] <= min(n1[2],n[2]): 
                temp.append(i) 
 
 
a2=time.time() 
for n in xp: 
    for n1 in xp: 
        xp_copy = copy.deepcopy(xp) 
        for i in xp: 
            if i[0] > min(n[0],n[0]) or i[1] > min(n[1],n[1]) or i[2] > min(n[2],n[2]): 
                xp_copy.remove(i) 
 
a3=time.time() 
for n in xp: 
    for n1 in xp: 
        output = [t for t in xp if t[0]<=min(n[0],n[0]) or t[1]<=min(n[1],n[1]) or t[2]<=min(n[2],n[2])] 
a4=time.time() 
 
for n in xp: 
    for n1 in xp: 
        l1 = sorted(xp, key=itemgetter(0), reverse=True) 
        l1_fitered = [] 
        for item in l1: 
            if item[0] <= min(n[0],n[0]): 
                break 
            l1_fitered.append(item) 
 
        l2 = sorted(l1_fitered, key=itemgetter(1), reverse=True) 
        l2_fitered = [] 
        for item in l2: 
            if item[1] <= min(n[1],n[1]): 
                break 
            l2_fitered.append(item) 
 
        l3 = sorted(l2_fitered, key=itemgetter(2), reverse=True) 
        l3_fitered = [] 
        for item in l3: 
            if item[2] <= min(n[2],n[2]): 
                break 
            l3_fitered.append(item) 
a5=time.time()             
 
 
 
print "soluce my_naive1, like proposed by Emil Vikström?",a2-a1 
print "soluce my_naive2",a3-a2 
print "soluce Tim Pietzcker",a4-a3 
print "soluce Don",a5-a4 

请您参考如下方法:

>>> l = [(0,0,4), (1,0,3), (1,2,1), (4,0,0)] 
>>> output = [t for t in l if t[0]>3 or t[1]>2 or t[2]>1] 
>>> output 
[(0, 0, 4), (1, 0, 3), (4, 0, 0)] 

这很快,因为 t[1]>2 仅在 t[0]>3 为 False 时才计算(与第三个条件)。因此在您的示例列表中,只需要进行 8 次比较。

如果您改用生成器表达式,您可能会节省时间和内存(取决于您对过滤后的数据执行的操作):

>>> l = [(0,0,4), (1,0,3), (1,2,1), (4,0,0)] 
>>> for item in (t for t in l if t[0]>3 or t[1]>2 or t[2]>1): 
>>>     # do something with that item