Matin Mohamadi | متین محمدی + منفرد
Matin Mohamadi | متین محمدی + منفرد
خواندن ۵ دقیقه·۲ سال پیش

جانشین های پرسرعت برای loop ها در پایتون!

اول کلام سلام .

در این مقاله سعی کردم یه موضوعی که شاید خیلیاتون بلد باشید ولی در عمل بکار نمیبرید رو بنویسم (بماند که خودمم تازه دارم عملی استفاده میکنم :)))) )


نمیگم حلقه ها بده ولی تا وقتی داده های ما کم و کوچیک هستن پاسخگوی مناسبی هست .

ولی تکلیف Data science چی میشه ؟ اونایی که با داده های خیلی بزرگ کار میکنن و استفاده از حلقه ها سرعت برنامشون رو به شدت پایین میاره !!

خب بزن بریم چنتا چیز جدید یاد بگیریم که جایگزین خوبی برای حلقه ها به حساب میاد ?


1 - استفاده از Filter :

با توجه به اسمش فکر کنم حدس زدید که چیکار میکنه .

اشیای iterable را برای ما فیلتر می کنه. ما می خوایم شرایط فیلتر را به صورت یک تابع منتقل کنیم و از این تابع برای فیلتر کردن هر عنصر در شی iterable استفاده می شه .


Syntax:

filter(function, iterable)

خب حالا بریم یه مقایسه ای داشته باشیم بین حلقه های for و while با Filter.

در اینجا، من لیستی از 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))

# Output
2499950000
0.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))

# Output
2499950000
0.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))

# Output
2499950000
0.022666 secs 1.087833 MByte


بریم سراغ بعدی

2 - استفاده از Map:

این تابع برای وقتی که بخواهید عملی رو روی تک تک اعضای iterable مثل لیست و تاپل و ... اعمال کنید .

syntax :

map(function, iterable)

حالا مثل قبلی یه مقایسه تر و تمیز مشاهده خواهیم کرددددد :


# 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))

#output
284654436382457541 .....................0420940313
12.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))

#output
284654436382457541 .....................0420940313
11.263874 secs 1.013439 MByte


# 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

#Output
284654436382457541 .....................0420940313
10.069755 secs 1.013439 MByte


2 - استفاده از Reduce:

پایتون تابعی به نام ()reduce ارائه می دهد که به شما امکان می دهد لیست را به روشی مختصرتر کاهش دهید. این تابع محاسبات تابعی را با در نظر گرفتن یک تابع و قابل تکرار مانند لیست، تاپل، سری و غیره به عنوان آرگومان انجام می دهد و یک مقدار واحد را به عنوان خروجی برمی گرداند.


Syntax:

reduce(function, iterable)

تابع ()reduce تابع دو آرگومان را به صورت تجمعی برای آیتم های لیست، از چپ به راست اعمال می کند تا لیست را به یک مقدار کاهش دهد.


برخلاف توابع map() و filter() , تابع reduce() یک تابع داخلی نیست و متعلق به ماژول functools است.


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

time_start = time.perf_counter()

sys.set_int_max_str_digits(0)

def addition(x,y):
return x + y

test_list = list(range(1, 1000000))

result = 0
for i in range(len(test_list)) :
result = addition(result, test_list[i])
print(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))

# Output
499999500000
0.289569 secs 0.167500 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 addition(x,y):
return x + y

test_list = list(range(1, 1000000))

result = 0
i=0
while i < len(test_list) :
result = addition(result, test_list[i])
i = i + 1
print(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))

# Output
499999500000
0.429485 secs 0.167500 MByte


Testing with a reduce function,

# Using Reduce from functools import reduce import time import resource import sys time_start = time.perf_counter() sys.set_int_max_str_digits(0) def addition(x,y): return x + y test_list = list(range(1, 1000000)) result = reduce(addition, test_list) print(result) time_elapsed = (time.perf_counter() - time_start) memMb=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024.0/1024.0 print (&quot%f secs %f MByte&quot % (time_elapsed,memMb)) # Output 499999500000 0.120981 secs 0.167500 MByte


در حال حاضر، تفاوت تنها در میلی ثانیه است. اما اگر مجموعه داده‌ای واقعاً بزرگ داشته باشیم، این میلی‌ثانیه‌ها به ثانیه و ساعت تبدیل می‌شوند.












loopdatascience
سرگرم ریاضیات - علوم کامپیوتر - هوش مصنوعی و حل یک مشکل از بشر ! علاقه مند به اقتصاد دیجیتال
شاید از این پست‌ها خوشتان بیاید