Python爬坑指北: 使用循环?你太out了!

138 阅读3分钟

微信公众号: 人人都能python编程 ,欢迎分享,非公众号转载保留此声明。

写在开头

作为Python从业者,我们总是处理大型数据集,并且经常需要修改一个或多个列。对这种任务使用循环很慢,是否有更加优雅的方法?。在这篇文章中,带您了解一些比 Python 中的循环更快的替代方法。让我们开始!

图片

Filter函数

根据名称我们很容易猜到它的作用。它为我们过滤可迭代对象。我们将以函数的形式传递过滤条件,这个函数将用于过滤可迭代对象中的每个元素。

函数原型:

filter(function, iterable)

现在让我们比较 python 过滤器与 for 循环和 while 循环的性能。在这里,我正在创建一个包含 100000 个连续项目的列表,然后将计算偶数的阶乘。最后,我们将对这些阶乘值求和。

# Using for loop
import math
import time
import resource
import sys

time_start = time.perf_counter()
sys.set_int_max_str_digits(0)
def factorial(n):   
    return math.factorial(n)
test_list = list(range(1, 100000))
result = []
for i in range(len(test_list)) :    
    if test_list[i] % 2 == 0:      
        result.append(test_list[i]) 
print(sum(result))
time_elapsed = (time.perf_counter() - time_start)
memMb=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024.0/1024.0
print ("%f secs %f MByte" % (time_elapsed,memMb))
# Output24999500000.041538 secs 1.082287 MByte
# Using while loop
import math
import time
import resource
import sys

time_start = time.perf_counter()
sys.set_int_max_str_digits(0)
def factorial(n):   
    return math.factorial(n)
test_list = list(range(1, 100000))
result = []
i=0
while i < len(test_list) :
    if test_list[i] % 2 == 0:
        result.append(test_list[i])
        i = i + 1 
print(sum(result))
time_elapsed = (time.perf_counter() - time_start)
memMb=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024.0/1024.0
print ("%f secs %f MByte" % (time_elapsed,memMb))
# Output24999500000.047446 secs 1.085056 MByte
# Using Filter
import math
import time
import resource
import sys

time_start = time.perf_counter()
sys.set_int_max_str_digits(0)
def factorial(n):   
    return math.factorial(n)
test_list = list(range(1, 100000))
result = filter(lambda x: x % 2 == 0, test_list)
print(sum((result)))
time_elapsed = (time.perf_counter() - time_start)
memMb=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024.0/1024.0
print ("%f secs %f MByte" % (time_elapsed,memMb))
# Output24999500000.022666 secs 1.087833 MByte

Map函数

如果您想将一个函数应用于可迭代对象(如列表、元组甚至 pandas 系列)的每个值,此函数非常有用。

函数原型:

map(function, iterable)

现在,让我们看看如何在 python 中使用 map 而不是循环。

# Using for loop
import math
import time
import resource
import sys

time_start = time.perf_counter()
sys.set_int_max_str_digits(0)
def factorial(n):   
    return math.factorial(n)
test_list = list(range(1, 10000))
result = 0
for i in range(len(test_list)) :
    test_list[i] = factorial(test_list[i])
    print(sum(test_list))
time_elapsed = (time.perf_counter() - time_start)
memMb=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024.0/1024.0
print ("%f secs %f MByte" % (time_elapsed,memMb))
#output284654436382457541 .....................042094031312.229430 secs 0.167130 MByte
# Using while loop
import math
import time
import resource
import sys

time_start = time.perf_counter()
sys.set_int_max_str_digits(0)
def factorial(n):   
    return math.factorial(n)
test_list = list(range(1, 10000))
result = 0
i=0
while i < len(test_list) :
    test_list[i] = factorial(test_list[i])
    i = i + 1 print(sum(test_list))
time_elapsed = (time.perf_counter() - time_start)
memMb=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024.0/1024.0
print ("%f secs %f MByte" % (time_elapsed,memMb))
#output284654436382457541 .....................042094031311.263874 secs 1.013439 MByte

现在,如果我们使用 map 函数运行相同的代码

# Using Map
import math
import time
import resource
import sys

time_start = time.perf_counter()
sys.set_int_max_str_digits(0)
def factorial(n):   
    return math.factorial(n)
    
test_list = list(range(1, 10000))
result = map(factorial, test_list)
print(sum((result)))
time_elapsed = (time.perf_counter() - time_start)
memMb=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024.0/1024.0
#Output284654436382457541 .....................042094031310.069755 secs 1.013439 MByte

总结

尽量避免在 Python 中完全使用循环通常不是一个好主意。循环是一种基本的编程结构,可让您多次重复一段代码。也就是说,在某些情况下,您可以使用替代构造来实现与循环相同的结果,而不必显式编写一个。类似的函数还有很多,比如Reduce,学一些类似的函数,可以在工作中以10X的提供我们的工作效率,也是非常有意义的一种投资。