Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在其他列表中进行有效的比较和插入循环_Python_Django_List_Loops - Fatal编程技术网

Python 如何在其他列表中进行有效的比较和插入循环

Python 如何在其他列表中进行有效的比较和插入循环,python,django,list,loops,Python,Django,List,Loops,我正在开发一个处理大型数据库的web应用程序(Python/Django),我需要优化这个循环以获得更好的执行时间 我有一个条目列表,每个条目都有一个yes\u count属性、一个no\u count属性和一个tid属性 我需要根据比率=是计数/(是计数+否计数)创建两个新列表 使用内置功能(或更快的功能)是更好的方法吗 yes\u条目=[] 无_条目=[] 对于e in条目: 如果在tid中包含e.tid: 如果e.yes\u count>0或e.no\u count>0: 比率=e.是计数

我正在开发一个处理大型数据库的web应用程序(Python/Django),我需要优化这个循环以获得更好的执行时间

我有一个条目列表,每个条目都有一个yes\u count属性、一个no\u count属性和一个tid属性

我需要根据比率=是计数/(是计数+否计数)创建两个新列表

使用内置功能(或更快的功能)是更好的方法吗

yes\u条目=[]
无_条目=[]
对于e in条目:
如果在tid中包含e.tid:
如果e.yes\u count>0或e.no\u count>0:
比率=e.是计数/(e.是计数+e.否计数)
如果比率>0.75:
是\u条目。追加(如tid)
elif比率<0.25:
无条目。追加(如tid)

我建议将
tid
设置为O(1)摊销查找速度的集合(与列表的O(N)相反):

for
循环之前,然后

if e.tid in set_tids

否则,您给出的其余代码看起来非常优化

您也可以通过只访问一次
e.tid
e.yes\u count
e.no\u count
来节省一些时间,并将它们存储在变量中:

for e in entries:
    tid = e.tid
    if tid in tids:
        yes_count = e.yes_count
        no_count = e.no_count
        if yes_count > 0 or no_count > 0:
            ratio = yes_count / (yes_count + no_count)
            if ratio > 0.75:
                yes_entries.append(tid)
            elif ratio < 0.25:
                no_entries.append(tid)
对于e-in条目:
tid=e.tid
如果tid中包含tid:
是计数=是计数
无计数=e.无计数
如果是\u计数>0或否\u计数>0:
比率=是计数/(是计数+否计数)
如果比率>0.75:
是\u条目。追加(tid)
elif比率<0.25:
无项目。追加(tid)
您还可以通过缓存no_entries.append和yes_entries.append来节省时间:

yes_entries_append = yes_entries.append
no_entries_append = no_entries.append

for e in entries:
    tid = e.tid
    if tid in tids:
        yes_count = e.yes_count
        no_count = e.no_count
        if yes_count > 0 or no_count > 0:
            ratio = yes_count / (yes_count + no_count)
            if ratio > 0.75:
                yes_entries_append(tid)
            elif ratio < 0.25:
                no_entries_append(tid)
yes\u entries\u append=yes\u entries.append
no_entries\u append=no_entries.append
对于e in条目:
tid=e.tid
如果tid中包含tid:
是计数=是计数
无计数=e.无计数
如果是\u计数>0或否\u计数>0:
比率=是计数/(是计数+否计数)
如果比率>0.75:
是\u条目\u追加(tid)
elif比率<0.25:
无项目附加(tid)
但在那一点上,你可能开始变得愚蠢了

另一个可能更愚蠢的尝试是看看使用过滤器是否更快。在python2中,filter返回一个列表,这意味着您要在它上面迭代两次,这不是理想的。然而,我们有itertools来帮助我们:

def filterfunc(e):
    return (e.tid in tids) and (yes_count > 0 or no_count > 0)

for e in itertools.ifilter(filterfunc, entries):
    tid = e.tid
    yes_count = e.yes_count
    no_count = e.no_count
    ratio = yes_count / (yes_count + no_count)
    if ratio > 0.75:
        yes_entries_append(tid)
    elif ratio < 0.25:
        no_entries_append(tid)
def filterfunc(e):
返回(如tid中的tid)和(是计数>0或否计数>0)
对于itertools.ifilter(filterfunc,条目)中的e:
tid=e.tid
是计数=是计数
无计数=e.无计数
比率=是计数/(是计数+否计数)
如果比率>0.75:
是\u条目\u追加(tid)
elif比率<0.25:
无项目附加(tid)
下一个问题是我们再次访问e上的字段两次。让我们用一些迭代器魔法来解决这个问题:

def filterfunc(t):
    tid, yes_count, no_count = t
    return (tid in tids) and (yes_count > 0 or no_count > 0)

for tid, yes_count, no_count in itertools.ifilter(filterfunc, itertools.imap(attrgetter(["tid", "yes_count", "no_count"]), entries)):
    ratio = yes_count / (yes_count + no_count)
    if ratio > 0.75:
        yes_entries_append(tid)
    elif ratio < 0.25:
        no_entries_append(tid)
def过滤器功能(t):
tid,是计数,否计数=t
返回(tid中的tid)和(是计数>0或否计数>0)
对于tid,itertools.ifilter中的yes\u count、no\u count(filterfunc、itertools.imap(attgetter([“tid”、“yes\u count”、“no\u count”]),条目)):
比率=是计数/(是计数+否计数)
如果比率>0.75:
是\u条目\u追加(tid)
elif比率<0.25:
无项目附加(tid)
由您和您的探查器从我建议的所有选项中确定最佳方法

另外,如果您使用的是python3,请使用
filter
而不是
itertools.ifilter
,因为它返回的是一个生成器,而不是python2版本的列表。

注意:下面是一个更紧凑的解决方案的尝试,不一定更高效。可能需要进行一些分析

我假设您正在检查
(e.yes\u count>0或e.no\u count>0)
,这样您就不会得到被零除的结果。假设这是一种非常罕见的情况,我将简单地将比率计算包装为一个处理
zeroDivisionError
异常的函数。在这种情况下,对于边的情况,我们返回零

def get_ratio(y, n):
    try:
        return y / (y + n)
    except ZeroDivisionError:
        return 0
接下来,我们创建一个生成器,它遍历条目并返回候选值的比率和tid

tidset = set(tids)  # assuming tids is not yet a set()
ratios = ((get_ratio(e.yes_count, e.no_count), e.tid) 
            for e in entries if e.tid in tidset)
最后,我们遍历生成器并将它们附加到适当的列表中:

yes_entries, no_entries = [], []
for ratio, tid in ratios:
    (yes_entries, no_entries)[ratio < 0.75].append(tid)
yes\u条目,no\u条目=[],[]
对于比率,tid的比率为:
(是项,否项)[比率<0.75]。追加(tid)

很好的建议,但我们实际上无法从代码片段中看出
tids
是否已经是
。如果条目中有“是/否”计数,那么您为什么不在数据库中执行此操作,它将比任何python代码都快。是的,正如@JochenRitzel所说,所有这些都可以在数据库中的单个查询中更高效地完成。这些技巧真的能提高性能吗?只是好奇。我对CPython有多聪明(或愚蠢?)知之甚少。是的,在某种程度上——但实际获得的数量在所有方面都是微不足道的,除了最紧密的循环。
tidset = set(tids)  # assuming tids is not yet a set()
ratios = ((get_ratio(e.yes_count, e.no_count), e.tid) 
            for e in entries if e.tid in tidset)
yes_entries, no_entries = [], []
for ratio, tid in ratios:
    (yes_entries, no_entries)[ratio < 0.75].append(tid)