وبلاگ رسانگار
با ما حرفه ای باشید

سرور مجازی NVMe

itertools پایتون – compress()، dropwhile()، takewhile() و groupby()

0 8
زمان لازم برای مطالعه: 6 دقیقه


معرفی

در این راهنما، ما نگاهی به روش استفاده از قدرت تکرارکننده ها با استفاده از Python خواهیم داشت itertools مدول.

این itertools ماژول یک رابط برای ایجاد تکرار کننده های سریع و کارآمد در حافظه در اختیار ما قرار می دهد. این تکرار کننده ها می توانند باشند بی نهایت، ترکیبی، یا خاتمه دادن.

Iterator در مقابل Iterable

یک اشاره گر یک نشانگر هوشمند است که می تواند راهنمایی کند (تکرار کردن) ما از طریق آیتم های یک تکرار پذیر (container) به ترتیب خاصی. لیستی از رنگ ها و همچنین لیستی از اعداد صحیح را در نظر بگیرید:

colors = ('red', 'blue', 'pink')
ints = (1, 3, 5, 4, 2)

حتی اگر این لیست‌ها را به ترتیب خاصی تعریف کرده‌ایم، وقتی در حافظه قرار می‌گیرند، لازم نیست به همان ترتیب ذخیره شوند:

iterators:  it1                 it2 
             V                   V
memory:     red   4   2   blue   1    3    pink   5

اگر به ترتیب حافظه را مرور کنیم، آن عنصر دوم را دریافت می‌کنیم colors آرایه است 4، به همین دلیل است که ما به تکرار کننده نیاز داریم.

وظیفه تکرار کننده این است که عنصر بعدی لیست را در حافظه پیدا کند، مهم نیست کجا باشد. این کار از طریق next() متدی که عنصر بعدی را که تکرار کننده به آن اشاره می کند برمی گرداند. it1 حافظه ای را که به آن دسترسی دارد جست و جو می کند و برمی گردد blue در حالی که it2 برمی گشت 3.

یکی از ویژگی‌های خوب تکرارکننده‌ها این است که می‌توانیم روش جستجوی عناصر را در تکرارپذیرهای مربوطه خود تعریف کنیم. برای مثال، می‌توانیم از آن بخواهیم که از همه اعداد فرد بگذرد و یک زیر مجموعه را برگرداند. این امر با اجرای یک سفارش به دست می آید next() روش یا با استفاده از داخلی itertools که به ما امکان می دهد تکرار کننده های خاصی را برای تکرار از طریق اشیا به روش های مختلف تولید کنیم.

ابزارهای تکراری که به آنها خواهیم پرداخت عبارتند از:

  • compress()
  • dropwhile()
  • takewhile()
  • groupby()

هرکدام از اینها توابع ایجاد تکرار شونده (آنها تکرار کننده تولید می کنند) می توانند استفاده شوند روی خود، یا ترکیبی.

این فشرده کردن() تابع

این compress(data, selector) تابع یک تکرار کننده ایجاد می کند که به طور انتخابی مقادیر را از بین انتخاب می کند data با توجه به لیست بولی – selector. اگر مقداری از data مطابق با a True ارزش در selector لیست، انتخاب خواهد شد و در غیر این صورت از آن صرفنظر می شود.

اگر data و selector هم اندازه نیستند، compress() متوقف می شود زمانی که یا data یا selector لیست ها تمام شده است:


from itertools import compress

cars = ('Audi', 'Volvo', 'Benz', 
        'BMW', 'Nissan', 'Mazda',
        'Ford')
        
selector = (True, True, False, False, 
            False, True, False)



my_cars = compress(cars, selector)

for each in my_cars:
    print(each)

این نتیجه در:

Audi
Volvo
Mazda

این selector همچنین می تواند لیستی از 1‘شن 0‘s یا هر مقدار درستی/نادرستی.

پیشنهاد می‌کنیم بخوانید:  نحوه تنظیم دقیق مدل دونات - با مثال مورد استفاده

شما معمولاً این لیست های بولی را از طریق نوعی شرایط به دست می آورید، مانند:

int_list = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
boolean_list = (True if x % 2 == 0 else False for x in int_list)



boolean_list = (1 if x % 2 == 0 else 0 for x in int_list)

print(boolean_list)

در اینجا، ما یک را تولید کرده ایم boolean_list با یک True برای هر عدد زوج:

(False, True, False, True, False, True, False, True, False, True)

# OR

(0, 1, 0, 1, 0, 1, 0, 1, 0, 1)

به طور معمول، برای کوتاه‌تر کردن موارد – از آن استفاده می‌کنید compress() ابزار، و همچنین ابزارهای دیگر، بدون تخصیص نتایج به یک متغیر جدید:

import itertools

word =  'rasanegar'
selector = (1, 0, 1, 0, 0, 0, 0, 1, 1, 1)

for each in itertools.compress(word, selector ):
    print(each)

نتیجه این است:

S
A 
U 
S 
E

علاوه بر این، از نظر فنی، می‌توانیم مقادیر موجود در آن را با هم ترکیب کنیم selector با هر مقدار درستی/نادرستی:

from itertools import compress

cars = ('Audi', 'Volvo', 'Benz',
        'BMW', 'Nissan', 'Mazda', 'Ford')


selector = (True, 1, 0, 0, '', 1, 'string')

for each in compress(cars, selector):
    print(each)

خروجی این است:

Audi
Volvo
Mazda
Ford

اگرچه، شایان ذکر است که مخلوط کردن سیب و گلابی مانند این است توصیه نمی شود.

این dropwhile() تابع

این dropwhile(criteria, sequence) تابع یک تکرار کننده ایجاد می کند که هر عنصر موجود در آن را رها می کند (از روی آن می گذرد). sequence، و برمی گردد True هنگام عبور از criteria تابع.

این criteria تابع معمولاً یک تابع لامبدا است اما لازم نیست که باشد. معمولاً، اگر یک تابع ساده باشد، به یک لامبدا کوتاه می شود، در حالی که توابع پیچیده اینگونه نیستند:

from itertools import dropwhile

int_list = (0, 1, 2, 3, 4, 5, 6)
result = list(dropwhile(lambda x : x < 3, int_list))

print(result)

با توجه به این تابع لامبدا، هر عنصر با مقدار کمتر از 3 بر خواهد گشت True، بنابراین همه عناصر کوچکتر از 3 نادیده گرفته می شوند. آنها هستند کاهش یافته است در حالی که معیار درست است:

(3, 4, 5, 6)

به جای یک تابع لامبدا، می‌توانیم یک تابع پیچیده‌تر تعریف کنیم و به جای آن یک مرجع به آن ارسال کنیم:

from itertools import dropwhile

def doesnt_contain_character(str):
    substring = 'a'
    if substring in str:
        return False
    else:
        return True
        
string_list = ('lorem', 'ipsum', 'dolor', 'sit', 'amet')
print(list(dropwhile(doesnt_contain_character, string_list)))

به عنوان مثال، این روش یک رشته را بررسی می کند شامل نمی شود آ substring – در این مورد، فقط a. اگر رشته داده شده شامل a، False برگردانده می شود و اگر حاوی آن نباشد – True برگردانده می شود. بنابراین، تمام کلمات در دنباله، تا amet برگشت True، و از نتیجه حذف می شوند:

('amet')

با این حال، همه عناصر پس از شکست معیارها شامل خواهد شد. در مورد ما، همه چیز بعد از 'amet' عنصر، بدون توجه به criteria:

from itertools import dropwhile

def doesnt_contain_character(str):
    substring = 'a'
    if substring in str:
        return False
    else:
        return True
        
string_list = ('lorem', 'ipsum', 'dolor', 'sit', 'amet', 'a', 'b')
print(list(dropwhile(doesnt_contain_character, string_list)))

این عناصر را تا زمانی که 'amet' و پس از آن از انداختن آنها منصرف می شود:

('amet', 'a', 'b')

این takewhile() تابع

این takewhile(criteria, sequence) تابع مخالف قطبی است dropwhile(). تمام عناصری را که عملکرد آنها خراب نمی شود حفظ می کند. بیایید مثال قبلی را بازنویسی کنیم تا بررسی کنیم که آیا یک کلمه وجود دارد یا خیر شامل یک شخصیت خاص:

پیشنهاد می‌کنیم بخوانید:  Odoo 12 را روی آن نصب کنید CentOS 7

بگذار چک کنیم:

from itertools import takewhile

def contains_character(str):
    substring = 'o'
    if substring in str:
        return True
    else:
        return False
        
string_list = ('lorem', 'ipsum', 'dolor', 'sit', 'amet')
print(list(takewhile(contains_character, string_list)))
('lorem')

از آنجا که criteria شکست می خورد روی عنصر دوم، حتی اگر 'dolor' همچنین شامل شخصیت است o – در نظر گرفته نشده است.

این دسته بندی بر اساس() تابع

این groupby(iterable, key_function) تابعی است که یک تکرار کننده ایجاد می کند که عناصر متوالی را که متعلق به یک گروه هستند را با هم ترکیب می کند. اینکه یک عنصر به یک گروه تعلق دارد یا نه بستگی دارد روی را key_function. را محاسبه می کند کلید مقدار برای هر عنصر، کلید ارزش در این مورد یک گروه خاص است شناسه.

یک خوشه به پایان می رسد، و یک خوشه جدید ایجاد می شود key_function یک شناسه جدید برمی گرداند، حتی اگر قبلا دیده شده باشد.

اگر key_function مشخص نشده است، سپس آن را به طور پیش فرض به تابع هویت. با این حال، شایان ذکر است که حتی با مقادیر تکراری – آنها نمی خواهد اگر با خوشه دیگری از هم جدا شوند با هم خوشه شوند:

from itertools import groupby

word = "aaabbbccaabbbbb"

for key, group in groupby(word):
    print(key, list(group))

به طور شهودی، ممکن است انتظار داشته باشید که همه موارد از آن استفاده شود a و b با هم دسته بندی شوند، اما از آنجایی که خوشه هایی بین آنها وجود دارد – آنها به خوشه هایی از خودشان جدا می شوند:

a ('a', 'a', 'a') 
b ('b', 'b', 'b') 
c ('c', 'c') 
a ('a', 'a') 
b ('b', 'b', 'b', 'b', 'b')

توجه داشته باشید: تنها راه برای جلوگیری از این امر این است که بر اساس تکرار شونده را از پیش تنظیم کنید روی کلیدها.

حالا بیایید یک عرف تعریف کنیم key_function، که می تواند یک تابع لامبدا یا اختصاصی باشد:

from itertools import groupby

some_list = (("Animal", "cat"), 
          ("Animal", "dog"),
          ("Animal", "lion"),
          ("Plant", "dandellion"),
          ("Plant", "blumen"))
  
for key, group in groupby(some_list, lambda x : x(0)):
    key_and_group = { key : list(group) }
    print(key_and_group)

ما فهرستی از تاپل ها تهیه کرده ایم، که در آن عنصر اول یک دسته بندی کلی را نشان می دهد – آیا یک ورودی یک حیوان یا الف گیاهو عنصر دوم نشان دهنده نام حیوان یا گیاه است.

سپس، ما اینها را بر اساس گروه بندی کرده ایم روی اولین عنصر، و چاپ هر عنصر دنباله:

{'Animal': (('Animal', 'cat'), ('Animal', 'dog'), ('Animal', 'lion'))}
{'Plant': (('Plant', 'dandellion'), ('Plant', 'blumen'))}

نتیجه

در این راهنما، نگاهی به آن انداخته ایم compress()، dropwhile()، takewhile() و groupby() ابزارهای تکرار در داخل پایتون itertools مدول.

اگر می خواهید در مورد آن بیشتر بدانید itertools ماژول و تکرار کننده ها به طور کلی، در صورت تمایل به سایر راهنماهای ما مراجعه کنید:

(برچسب‌ها به ترجمه)# python



منتشر شده در 1403-01-10 00:36:03

امتیاز شما به این مطلب
دیدگاه شما در خصوص مطلب چیست ؟

آدرس ایمیل شما منتشر نخواهد شد.

لطفا دیدگاه خود را با احترام به دیدگاه های دیگران و با توجه به محتوای مطلب درج کنید