有没有一种方法可以更快地进行循环

时间:2020-05-23 18:02:13

标签: python performance loops

我希望能够进行一次迭代,以检查仅将数字作为条目的列表值的条件。如果它通过了条件测试,那么我想将其添加到新列表中。不幸的是,由于并非所有值都将添加到同一列表中,所以我认为我无法进行列表理解。

我希望能够做到这一点:

def sort(values: []):
    sum_0 = sum(values)
    len_0 = len(values)
    average_0 = sum_0 / len_0
    lesser_list_0 = []
    greater_list_0 = []
    for value in values:
        if value >= average_0:
            greater_list_0.append(value)
        else:
            lesser_list_0.append(value)

但是不会因为for循环而变慢。另外,是否有比使用append方法更快的方法将值添加到任一列表的末尾?

3 个答案:

答案 0 :(得分:2)

由于您需要读取所有值才能执行此计算,因此您将需要“某种循环”。您不想做的是在关心速度的数值计算中使用Python循环。

我建议您看看一些专门用于数值计算的库。特别地,请看一下numpy。您具有轻松计算平均值的函数,并且numpy具有非常强大的索引功能,您可以在其中索引具有单个值,整数数组,布尔数组等的数组。

检查以下代码,我们将一个数组与一个标量(平均值)进行比较,以获取布尔数组。然后,我们可以使用此布尔数组来仅获取原始数组中相应布尔值为True的值。这将为您提供想要的东西。

import numpy as np


def separate_values(values: np.ndarray):
    average = np.mean(values)

    # This will gives an array of Boolean with the same dimension of `values`
    # and True only in places where the value is lower than the average
    mask1 = values < average
    mask2 = np.logical_not(mask1)  # We could also just write `values >= average`

    # We can use the boolean mask to index the original array.
    # This will gives us an array with the elements lower than the average
    lesser = values[mask1]
    # This will gives us an array with elements greater than or equal to the average
    greater = values[mask2]

    # Returns a tuple with both arrays
    return lesser, greater


if __name__ == '__main__':
    # A random array with 5 integers in the interval (0, 10]
    values = np.random.randint(0, 10, 5)

    lesser, greater = separate_values(values)

    print("Average:", np.mean(values))
    print("Values:", values)
    print("Values < average:", lesser)
    print("Values >= average:", greater)

您需要安装numpy才能使其正常工作。它可以通过pip,conda等轻松安装。

答案 1 :(得分:0)

是的,您可以使用pandas和numpy库进行这些操作。 这些库针对这些操作进行了优化。 他们使用c数据类型和并发性以及多重处理和...。

https://pandas.pydata.org/pandas-docs/stable/10min.html

您必须使用切片和子集。它的工作原理是这样,但并非必须如此,您必须参考docs: specific_value = values_mean my_datafram [my_dataframe ['values']> = specific_value]

您可以使用以下方法计算均值非常有效: https://www.geeksforgeeks.org/python-pandas-dataframe-mean/

答案 2 :(得分:0)

列表推导也是循环的,您真正保存的只是在每一回合中查找greater_list_0.appendlesser_list_0.append。在创建两个列表时,for循环会更快。您可以通过预先预想所需的两个append方法来节省少量时间。对于下面显示的3种情况,我的计算机上的计时是

for loop 1.0464496612548828
comprehensions 1.1907751560211182
less lookup 0.9023218154907227

测试代码是

import random
import time

def sort(values: []):
    sum_0 = sum(values)
    len_0 = len(values)
    average_0 = sum_0 / len_0
    greater_list_0 = []
    lesser_list_0 = []
    for value in values:
        if value >= average_0:
            greater_list_0.append(value)
        else:
            lesser_list_0.append(value)

def sort2(values: []):
    sum_0 = sum(values)
    len_0 = len(values)
    average_0 = sum_0 / len_0
    greater_list_0 = [val for val in values if val >= average_0]
    lesser_list_0 = [val for val in values if val < average_0]

def sort_less_lookup(values: []):
    sum_0 = sum(values)
    len_0 = len(values)
    average_0 = sum_0 / len_0
    greater_list_0 = []
    lesser_list_0 = []
    g_append = greater_list_0.append
    l_append = lesser_list_0.append
    for value in values:
        if value >= average_0:
            g_append(value)
        else:
            l_append(value)

values = list(range(100000))
random.shuffle(values)

tries = 100
start = time.time()
for _ in range(tries):
    sort(values)
delta = time.time() - start
print('for loop', delta)

start = time.time()
for _ in range(tries):
    sort2(values)
delta = time.time() - start
print('comprehensions', delta)

start = time.time()
for _ in range(tries):
    sort_less_lookup(values)
delta = time.time() - start
print('less lookup', delta)