Barcha qo'llanmalar

Python reduce(): to'liq qo'llanma (misollar bilan)

Python'dagi reduce() real misollarda qanday ishlashini, keng tarqalgan tuzoqlarni hamda qachon list comprehension'lar yoki loop'lar oqilonaroq tanlov ekanini bilib oling.

Muallif: Kimberly Fessel

Bugungi kunda tashkilotlar hech qachon tahlil qilishga ulgurmaydigan darajada ko'p ma'lumot to'plamoqda. Chuqur xulosalar beradigan big data ne'mati umumlashtirilishi kerak bo'lgan ma'lumotlar uyumlari orasida yo'l topish la'nati bilan yonma-yon keladi. Sizning Python collection'ingiz to'ppa-to'g'ri Hoarders ko'rsatuvining bir epizodiga o'xshab ketishi mumkin. Agar ma'lumotlarni aggregate qilish va ortiqchasidan tozalashga kuchli ishtiyoq sezayotgan bo'lsangiz, Python'ning reduce() funksiyasi aynan siz izlagan funksiya bo'lishi mumkin.

Ushbu maqolada reduce()'ni batafsil tahlil qilamiz: u nima, qanday ishlaydi, shuningdek chuqur tushunish uchun ko'plab misollar. Agar map(), filter(), reduce() uchligi siz uchun yangi bo'lsa, bu uchtasi functional programming bilan qanday bog'liqligini tushuntiramiz. Shuningdek, reduce() funksiyasidan qachon foydalanish va qachon uning o'rniga boshqa Pythonic variantlarni afzal ko'rish kerakligini ham ko'rib chiqamiz.

Python'da reduce() funksiyasi nima?

Python'ning reduce() funksiyasi bitta qiymat hosil qilish uchun iterable'dagi elementlarni takroran birlashtiradi. U Python standard library'sining bir qismi bo'lgan functools module'idan keladi. Butun qiymatlar to'plami bo'ylab bir xil amalni bajarish kerak bo'lganda reduce() eng foydali ekanini ko'rasiz. Yakuniy natija ko'pincha bitta son bo'lsa-da, u istalgan obyekt bo'lishi mumkin, jumladan string, list yoki dictionary. Python reduce() odatda bajaradigan ko'plab amallar uchun maxsus funksiyalar yoki method'larni o'z ichiga oladi (masalan, sum(), min(), max(), str.join() va hokazo), shuning uchun u Python'da boshqa ko'plab dasturlash tillaridagiga qaraganda kamroq uchraydi.

reduce() qanday ishlaydi

reduce() ikkita argument talab qiladi: funksiya va iterable. Bu funksiya argument'i foydalanuvchi aniqlagan funksiya yoki lambda funksiya bo'lishi mumkin. reduce() funksiyani kumulyativ tarzda qo'llab, iterable'dagi elementlarni chapdan o'ngga qayta ishlaydi. Funksiyaning o'zi ham ikkita argument qabul qilishi kerak: shu paytgacha to'plangan natija va joriy element. Funksiya har safar chaqirilganda uning qaytargan qiymati yangilangan to'plangan natijaga aylanadi va reduce() iterable'ingizdagi barcha elementlarni qayta ishlab bo'lguncha shu tarzda davom etadi.

Buni tushunib olish uchun oddiy misol keltiramiz. reduce() funksiyasi list'dagi elementlarni kumulyativ tarzda birma-bir aylanib chiqadi va har birini joriy yig'indiga takroran qo'shib, list'dagi barcha qiymatlarning yakuniy yig'indisiga yetib keladi.

reduce(add, [1, 2, 3, 4])

reduce() bularni boshlang'ich qiymat 1 dan boshlab, qolgan har bir qiymatni birma-bir qo'shib qayta ishlaydi:

  • 1 + 2 → 3

  • 3 + 3 → 6

  • 6 + 4 → 10

List tugagach, u umumiy yig'indi bo'lgan 10 ni qaytaradi.

Bu yerda add ikkita qiymat qabul qilib, ularning yig'indisini qaytaradigan maxsus yozilgan funksiyani ifodalaydi. Keyingi bo'limda bu funksiyani qanday yozishni ko'rsatamiz: ham nomlangan funksiya, ham lambda funksiya sifatida.

reduce()'ning amaliy misollari

Endi Python'dagi reduce() nima ekani va u umuman qanday ishlashini bilganingizdan so'ng, Python'dagi reduce() funksiyasining bir nechta amaliy namoyishiga sho'ng'iymiz. E'tibor bering, reduce() barcha misollarda ikkita argument talab qiladi.

reduce() yordamida qiymatlarni yig'ish

List'dagi sonli qiymatlarni yig'ish misolimizga qaytaylik. functools'dan reduce()'ni import qiling. So'ng add()'ni quyidagicha aniqlashingiz mumkin:

from functools import reduce

def add(a, b):
    return a + b

values = [1, 2, 3, 4]

total = reduce(add, values)

print(total)

# Expected result:
# 10

add() funksiyasining har bir chaqiruvida ikkita kiruvchi qiymat qo'shiladi. reduce() natijani list'ning keyingi elementi bilan birga keyingi chaqiruvda add()'ga kiruvchi qiymatlar sifatida beradi va bu barcha qiymatlar aylanib chiqilib, bitta kumulyativ qiymat qolguncha davom etadi. Shuningdek, funksiya nomi add'ni qavslarsiz uzatayotganimizga e'tibor bering. Bu reduce()'ga funksiyani takroran chaqirish va reduction jarayoniga muvofiq argument'larni berish imkonini beradi.

Minimal va maksimal qiymatlarni topish

reduce() funksiyasidan list'dagi minimal va maksimal qiymatlarni topish uchun ham foydalanishingiz mumkin. Ikkalasini topish uchun bu kod ikkita alohida nomlangan funksiya va reduce() chaqiruvlaridan foydalanadi:

from functools import reduce

def find_min(current_min, x):
    if x < current_min:
        return x
    else:
        return current_min

def find_max(current_max, x):
    if x > current_max:
        return x
    else:
        return current_max

values = [7, 2, 4, 10, 6]

min_value = reduce(find_min, values)
max_value = reduce(find_max, values)

print(f"The minimum is {min_value}, and the maximum is {max_value}.")

# Expected result:
# The minimum is 2, and the maximum is 10.

reduce() minimal va maksimal qiymatlarni topa olsa-da, Python'ning built-in min() va max() funksiyalari ancha soddaroq va o'qish oson kodga olib keladi. Bu masalaga keyinroq reduce() funksiyasidan qachon qochish kerakligi haqidagi bo'limda qaytamiz.

Maxsus taqqoslash bilan maksimal qiymatni olish

Yodda tuting, reduce() funksiyasi faqat sonli qiymatlar uchun emas. Siz string'larni, dictionary elementlarini, alohida list'larni yoki deyarli istalgan Python obyektini taqqoslashingiz mumkin. Iterable ham albatta list bo'lishi shart emas. U shunchaki Python elementlarini birma-bir qayta ishlay oladigan iterable obyekt bo'lsa kifoya.

Endi tuple'dagi eng uzun string'ni topish uchun reduce()'dan foydalanamiz. Har bir chaqiruvda reduce() ikki string uzunligini taqqoslaydi va qaysi birida belgilar ko'proq bo'lsa, o'shani saqlab qoladi. U faqat eng uzun string qolguncha shunday davom etadi.

from functools import reduce

def find_longest(word1, word2):
    if len(word1) >= len(word2):
        return word1
    else:
        return word2

subjects = ("music", "math", "geography", "art")

longest_subject = reduce(find_longest, subjects)

print(longest_subject)

# Expected result:
# geography

Bu holatda "maksimum" son emas, balki eng uzun string. Python'ning built-in max() funksiyasi ham o'zining key argument'i orqali bunday masalani hal qila oladi, ammo reduce() maksimal elementni aniqlash uchun takroriy taqqoslashlarni qanday qo'llashimiz mumkinligini tushunishning oddiy usulini taklif etadi.

reduce()'da lambda funksiyalardan foydalanish

Hozirgacha siz reduce()'ni foydalanuvchi aniqlagan funksiyalar bilan birga ko'rdingiz, lekin reduce()'da lambda funksiyalarni ham tez-tez uchratasiz. Lambda funksiyalar — kodingizda ko'pincha faqat bir marta ishlatiladigan kichik, anonymous funksiyalar. Ular sizni biroz yozishdan tejashi mumkin, ammo chalkashlikka yo'l qo'ymaslik uchun tabiatan ancha sodda bo'lishi kerak.

Quyida dastlabki qiymatlarni yig'ish misolimiz nomlangan funksiya o'rniga lambda funksiya bilan qayta yozilgan:

from functools import reduce

values = [1, 2, 3, 4]

total = reduce(lambda x, y: x + y, values)

print(total)

# Expected result:
# 10

E'tibor bering, oldingi misolda add'ni qavslarsiz uzatganimiz kabi, lambda'ni ham to'g'ridan-to'g'ri reduce()'ga uzatamiz. Lambda expression'dagi birinchi parametr x to'plangan natijani, y esa list'ning joriy elementini ifodalaydi. Lambda funksiya bilan ham, nomlangan funksiya yondashuvi bilan ham bir xil natijaga erishamiz; ikki variant orasidagi tanlov shunchaki kod bo'yicha shaxsiy afzallik va o'qilishi osonligiga bog'liq.

Initializer qo'shish

reduce() ikkita argument talab qiladi: to'plash uchun ishlatiladigan funksiya va iterable, biroq reduce() funksiyasi initializer uchun ixtiyoriy uchinchi argument'ni ham qabul qiladi: reduce(function, iterable, initializer). reduce()'ni chaqirganingizda default xatti-harakat iterable'ning birinchi elementini boshlang'ich qiymat sifatida ishlatadi. Biroq initializer argument'i orqali boshqa qiymatdan boshlashingiz mumkin. Shunda initializer reduce() funksiyani iterable'ga qo'llashidan oldingi birinchi to'plangan qiymatga aylanadi.

Initializer ayniqsa to'plash muayyan boshlang'ich qiymatdan boshlanishi kerak bo'lganda yoki bo'sh iterable'larni qayta ishlashda juda qo'l keladi. Yig'ish misolimizga iterable sifatida bo'sh list uzatish initializer'siz xatoga olib keladi, chunki boshlang'ich to'plangan qiymat sifatida ishlatiladigan birinchi element yo'q. Buning o'rniga muammolarga yo'l qo'ymaslik uchun yig'indimizni 0 boshlang'ich qiymatidan boshlashimiz mumkin:

from functools import reduce

empty_values = []

total = reduce(lambda x, y: x + y, empty_values, 0)

print(total)

# Expected result:
# 0

reduce() parda ortida

Endi reduce() funksiyasi nimalar qila olishini his qilib olganingizdan so'ng, reduce()'ning xatti-harakati va functional programming bilan bog'liqligini tushuntirib beradigan bir nechta Python tushunchasini bilib olishga arziydi.

Higher-order function nima?

Higher-order function funksiyani kirish sifatida qabul qiladi, funksiyani natija sifatida qaytaradi yoki ikkalasini ham bajaradi. Python'ning reduce() funksiyasi higher-order function'ga misol, chunki u birinchi argument sifatida funksiya qabul qiladi. Unga yaqin map() va filter() funksiyalari ham higher-order hisoblanadi. Hatto max() va sorted() kabi built-in funksiyalar ham ixtiyoriy key argument'i orqali funksiya qabul qilgani uchun higher-order function sanaladi.

Callable obyektlar va reduce()

reduce()'ning birinchi argument'i callable obyekt bo'lishi kerak, ya'ni qavslar bilan chaqirish mumkin bo'lgan har qanday narsa. Callable'larga misollar:

  • Nomlangan funksiyalar

  • Lambda funksiyalar

  • Built-in funksiyalar

  • __call__() method'iga ega obyektlar

Odatda bu birinchi o'rinni funksiyalar egallaganini ko'rasiz, ammo tajribali foydalanuvchilar __call__() method'i bilan aniqlangan maxsus sinflarning instance'larini ham uzatishlari mumkin.

Functional programming'da reduce()

Functional programming — funksiyalarga first-class obyekt sifatida qaraydigan dasturlash uslubi. U odatda ma'lumotlarni qayta ishlash uchun kichik funksiyalarni birgalikda ishlatadi. Functional programming ma'lumotlarni mos ravishda transform qilish, filtrlash va aggregate qilish uchun higher-order map(), filter(), reduce() funksiyalariga katta tayanadi. Python functional programming'ni qo'llab-quvvatlasa-da, u sof functional til emas. Ko'plab dasturchilar aniq, samarali kod yozish va Python ko'nikmalarini o'tkir saqlash uchun functional va imperative uslublarni aralashtirishga moyil.

reduce() Python 3'da Python'ning functools module'iga ko'chirildi, chunki u boshqa ko'plab built-in funksiyalarga qaraganda kamroq ishlatilardi. map() va filter()'ni esa hali ham Python'ning asosiy codebase'ida topasiz.

reduce()'dan qachon qochish kerak

reduce() kuchli higher-order function va functional programming uchun muhim bo'lsa-da, ko'pincha u eng o'qilishi oson yechim bo'lmaydi. Ushbu bo'limda reduce() o'rniga boshqa yondashuvlarni tanlashingiz mumkin bo'lgan bir nechta muhim holatni ko'rib chiqamiz.

reduce() va built-in funksiyalar

Python 3'dan boshlab ishni boshlash uchun sizga from functools import reduce kerak bo'ladi, chunki reduce()'ning ko'plab keng tarqalgan qo'llanish holatlari built-in funksiyalar yordamida tozaroq hal qilinadi. Masalan, avval ko'rib chiqqan yig'ish misolimizni olaylik. Python'dagi built-in sum() funksiyasi list'lar va boshqa iterable'larni o'qish osonroq kod bilan yig'adi:

values = [1, 2, 3, 4]

total = sum(values)

print(total)

# Expected result:
# 10

Xuddi shunday, min() va max() minimal va maksimal qiymatlarni to'g'ridan-to'g'ri topadi va ular ko'plab sonli bo'lmagan data type'lar bilan ham ishlaydi. Umumiy qoida sifatida, Python'ning built-in funksiyalari niyatingizni aniqroq ifodalagan har safar reduce() o'rniga ularga tayaning.

Muqobillar: list comprehension'lar, loop'lar, itertools.accumulate()

Gap Python haqida ketganda, reduce() iterable ma'lumotlarni qayta ishlashning yagona usuli emas. Quyida ba'zi tegishli muqobillarga qisqacha nazar tashlaymiz.

List comprehension'lar ma'lumotlarni transform qilish yoki filtrlashning kuchli usulini taklif etadi; biroq ular bitta qiymatga reduce qilish o'rniga boshqa iterable hosil qiladi. Natijada list comprehension'lar odatda reduce() o'rniga emas, ko'proq map() funksiyasi yoki filter() funksiyasi o'rnini egallaydi.

Iterable'larni qayta ishlashda for loop'larni ham uchratasiz. Ular bir nechta conditional statement yoki bir nechta to'plash bosqichi kabi murakkabroq mantiqni amalga oshirishda foydali. for loop'lari ham bitta kumulyativ qiymatga olib kelishi mumkin va ularni ko'pincha reduce()'ga qaraganda debug qilish osonroq. Qo'shimcha oraliq bosqichlar kerak bo'lib qolsa, ularni o'zgartirish ham osonroq bo'lishi mumkin.

Python'dagi accumulate() funksiyasi itertools module'ida joylashgan. U ham iterable'lar ustida kumulyativ tarzda ishlaydi, ammo reduce() kabi bitta qiymat qaytarish o'rniga sizga har bir to'plangan qiymatni beradi. Bu ayniqsa jamlanib boruvchi yig'indilar, kumulyativ ko'paytmalar va hokazolar uchun foydali hamda funksiyangiz qiymatlarni to'g'ri to'playotganini tekshirishga yordam beradi.

Quyidagi kod yig'ish misolimizdagi bilan bir xil iterable va callable sifatida bir xil funksiya yordamida itertools.accumulate()'ni namoyish etadi:

from itertools import accumulate

values = [1, 2, 3, 4]

running_total = list(accumulate(values, lambda x, y: x + y))

print(running_total)

# Expected result:
# [1, 3, 6, 10]

reduce()'dan farqli o'laroq, accumulate() iterable'ni birinchi argument sifatida kutadi va to'plash funksiyasini ixtiyoriy ikkinchi argument sifatida qabul qiladi. U to'plangan qiymatlardan iborat iterator qaytaradi; uni list'ga aylantirish orqali qiymatlarini olishingiz mumkin.

Python'dagi ko'pchilik mavzular singari, eng yaxshi yechim aniq vazifangizga bog'liq. Ayniqsa Python ko'plab turli dasturlash paradigmalarini qo'llab-quvvatlashini hisobga olsak, functional programming uslubini majburlashdan ko'ra o'qilishi osonlikni ustun qo'ying.

Data science'dagi qo'llanish holatlari

Data scientist'lar ma'lumotlar bilan ishlash uchun muntazam ravishda pandas va NumPy kutubxonalariga tayanadi va odatda reduce() bu kutubxonalarning birortasi bilan birga ishlatilganini ko'rmaysiz, chunki ularning o'z aggregation method'lari bor. Biroq data science masalalarida murakkabroq obyektlarni takroran birlashtirishda reduce()'ni uchratasiz.

Ma'lumotlar tuzilmalari bilan murakkabroq misol

Sonlar va matndan tashqari, reduce() dictionary'lar kabi murakkabroq obyektlarni ham birlashtira oladi. Aytaylik, sizda veb-saytning kunlik sahifa ko'rishlarini qayd etadigan dictionary'lar list'i bor. Agar har bir sahifaning jami ko'rishlarini tahlil qilish uchun shu list'ni bitta dictionary'ga birlashtirmoqchi bo'lsangiz, reduce()'dan quyidagiga o'xshash kodda foydalanishingiz mumkin:

from functools import reduce

daily_views = [
    {"home": 21, "about": 10},
    {"home": 10, "about": 2, "blog": 5},
    {"home": 12, "contact": 3},
    {"home": 5},
    {"home": 10, "blog": 4}
]

def combine_views(total, daily):
    for page, views in daily.items():
        total[page] = total.get(page, 0) + views
    return total

total_views = reduce(combine_views, daily_views, {})

print(total_views)

# Expected result:
# {'home': 58, 'about': 12, 'blog': 9, 'contact': 3}

Bu kod har bir kunlik dictionary'ni qayta ishlaydi, reduce() funksiyasi esa mos sahifalar uchun sonlarni qo'shib, jami sahifa ko'rishlarini kumulyativ tarzda bitta asosiy dictionary'ga birlashtiradi. Agar sahifa kunlik dictionary'da bo'lmasa, .get() xato chiqarish o'rniga nol qaytaradi. Shuningdek, daily_views bo'sh list bo'lib qolgan holat uchun initializer sifatida bo'sh dictionary'dan boshlaymiz.

Built-in aggregation funksiyalari ko'plab keng tarqalgan vazifalarni qamrab olsa-da, murakkabroq ma'lumotlar tuzilmalarini takroran bitta natijaga birlashtirish kerak bo'lganda reduce() data science uchun kuchli vosita bo'lib qolaveradi.

Keng tarqalgan tuzoqlar

Foydaliligiga qaramay, reduce() funksiyasining siz bilishingiz kerak bo'lgan bir nechta keng tarqalgan "tuzoq"lari ham bor. Python kodingizda muammolarga yo'l qo'ymaslik uchun quyidagi asosiy tuzoqlarni ko'rib chiqing.

Initializer'ning yo'qligi

Agar initializer qiymatini bermasangiz, reduce() to'plashni iterable'ingizdagi birinchi qiymatdan boshlaydi. Demak, iterable bo'sh bo'lishi mumkin bo'lgan har safar initializer uzatishingiz kerak; aks holda boshlash uchun default qiymat bo'lmaydi va TypeError olasiz.

Bu misol bo'sh generator va initializer boshlang'ich qiymati yo'qligi orqali muammoni ko'rsatadi:

from functools import reduce

values = (x for x in range(10) if x > 20)

total = reduce(lambda x, y: x + y, values)

print(total)

# Expected result:
# TypeError: reduce() of empty iterable with no initial value

Muammoni tuzatish uchun initializer bering, shunda iterable bo'sh bo'lganda ham reduce() funksiyasining boshlang'ich qiymati bo'ladi:

total = reduce(lambda x, y: x + y, values, 0)

Callable'dan noto'g'ri qiymat qaytarish

reduce()'ga uzatadigan callable funksiyangiz har bir chaqiruvdan keyin to'plangan qiymatni qaytarishi kerak. reduce() funksiyasi bu qaytgan qiymatni keyingi iteration uchun accumulator sifatida ishlatadi.

Bu talab oddiy ko'rinsa-da, amalda uni buzish oson. Data science'dagi sahifa ko'rishlari misollarida quyidagi callable ishlamaydi, chunki .update() method'i dictionary'larni in-place o'zgartiradi va None qaytaradi:

lambda x, y: x.update(y)

Nomlangan funksiyadan yoki lambda funksiyadan foydalanasizmi, u yangilangan to'plangan qiymatni qaytarishiga ishonch hosil qiling; aks holda reduce() keyingi qiymatni qayta ishlashda to'g'ri accumulator'ga ega bo'lmaydi.

Xulosa

Python'dagi reduce() funksiyasi iterable'dagi elementlarni bitta qiymatga birlashtiradi. Uni Python'ning functools module'ida topasiz, umumiy sintaksisi esa reduce(function, iterable, initializer) ko'rinishida bo'lib, bunda initializer boshlang'ich qiymat uchun ixtiyoriy uchinchi argument. reduce() qiymatlarni takroran bitta natijaga qo'shib borishda, ayniqsa sonli qiymatlarni ko'paytirishda va dictionary'larni birlashtirish kabi murakkab aggregation vazifalarida eng foydali.

Qiymatlarni yig'ish yoki maksimum va minimumlarni topish kabi keng tarqalgan vazifalar uchun Python'dagi boshqa funksiyalar ko'pincha o'qilishi osonroq yechimlarni taqdim etsa-da, reduce() funksiyasi maxsus to'plash mantig'i uchun qimmatli higher-order function bo'lib qolaveradi.

AI Tutor bilan muloqot qilib, kodingizda reduce()'dan qachon foydalanish haqida ko'proq bilib oling. Ushbu prompt boshlab olishga yordam beradi:

Yo'l xaritalariQo'llanmalarFAQYouTube

yo'lxaritaroadmap.shasosida

Hamjamiyat tomonidan yaratilgan yo'l xaritalari, eng yaxshi amaliyotlar, loyihalar, maqolalar, manbalar va yo'nalishlar — o'z yo'lingizni tanlash va kasbingizda o'sish uchun.

© yo'lxarita·Shartlar·Maxfiylik·

roadmap.sh

Barcha kontent roadmap.sh loyihasidan olingan (© Kamran Ahmed) va shaxsiy o'rganish uchun o'zbek tiliga tarjima qilinmoqda.

Qidiruv

Yo'l xaritalari, loyihalar va savollarni qidiring