Bájos python kombinatorikus funkciók a modul itertools

Ez a tartalom része a sorozat: Charming Python

Stay tuned a közelgő cikkek ebben a sorozatban.

Magyarázat az új koncepció

A koncepció a iterátorokat vezetünk Python 2.2-es verzió. Bár ez nem teljesen igaz; tippeket az ötlet már jelen voltak a korábbi funkció xrange () metódus a fájl .xreadlines (). Python 2.2 generalizált ezt a fogalmat sok belső megvalósítások és jelentősen egyszerűsített programozási egyéni iterátorok, beírja a kulcsszó hozam (kitermelés jelenléte átalakítja a funkció generátort, ami viszont vissza egy iterátor).

iterátorokat vonzóak, két okból. Munka adatok sorozata - gyakran a legegyszerűbb, és a sorrend kerül feldolgozásra lineáris sorrendben, sőt, gyakran nem is létezik egyszerre.

Figyelmeztetések x * () nyújt nyilvánvaló példái ezeknek az elveknek. Ha azt szeretnénk, hogy tegyen valamit a milliárd alkalommal, a program valószínűleg futni egy ideig, de általában nem kell sok memóriát neki. Hasonlóképpen, a sokféle fájl feldolgozása végezhető el soronként, és nincs szükség, hogy tárolja a teljes fájl memóriába. Mindenféle más szekvenciák legjobban kezelni lustán; tudtak támaszkodni szolgáltatott adatok formájában lépésekben a csatorna, vagy elvégzett számítások lépésről lépésre.

bejáró legtöbb időt használják hurok ugyanúgy, mint az igazi szekvencia. Iterátorokat biztosítja .next () () metódus, hogy lehet hivatkozni explicit módon, de 99% -át az időt, amit lát - ez olyasmi, mint:

Ez a hurok ér véget, amikor a hátsó hivatkozás iterator.next () dob kivételt StopIteration. Mellesleg, az igazi szekvencia lehet alakítani egy bejáró hívja iter (seq) - nem a memóriát, de hasznos lehet, amint azt az alábbi funkciókat.

Python progresszív tudathasadás

Python attitûdjeit funkcionális programozási van valami skizofrén. Egyrészt sok Python fejlesztők leszólni a hagyományos FP funkciók: térkép (). szűrő (). és csökkenti () - rendszerint ajánló használatával lista comprehensions helyett (lista comprehensions). De a teljes modul alkotja itertools funkciók pontosan ugyanaz a fajta, pusztán működő „lusta szekvenciák” (iterátorokat) helyett befejezett szekvenciák (listák, hármas). Sőt, Python 2.3 nincs szintaxis „bejáró megértés” (bejáró comprehensions), ami úgy tűnik, hogy ugyanaz a motívumok, amelyek felsorolják comprehensions.

Gyanítom Python hosszú távon növekedni valamilyen formában bejáró megértés, de ez attól függ, hogy megtalálja a megfelelő természetes szintaxis számukra. Közben van számos hasznos funkciót kombinatorikus itertools modult. Általában minden ilyen funkciót vesz néhány paraméter (általában köztük néhány alapvető iterátorokat) és visszatér egy új bejáró. Például, IFilter () függvény. imap () és izip () teljesen egyenértékű a megfelelő beépített függvények, amelyek nem rendelkeznek a kezdeti i.

hiányzó ekvivalens

A ireduce () nem itertools. Bár úgy tűnhet, természetes; lehetséges Python végrehajtása:

1. lista A kiviteli alak ireduce ()

Felhasználási eset ireduce () hasonló a kiviteli alak, hogy csökkentse () (). Tegyük fel például, a felvenni kívánt számok listáját, amelyek egy nagy fájlt, de megáll, ha a feltétel. Lehet ellenőrizni a kimenetele a jelenlegi révén:

2. lista hozzáadása számok listáját és következtetések

Egy reális példa erre talán valami hasonló az események láncolatába tárgyakra, amelyek támogatják a belső állapot, például egy grafikus felhasználói felület ellenőrzés. De még az egyszerű példa azt mutatja bejáró combinators a stílus funkcionális programozás.

Gyári alap iterátorokat

Minden funkció itertools modul könnyen megvalósítható tiszta Python generátorok. A lényeg ez a modul Python 2.3+ - így a normál működését és a nevét néhány hasznos funkciókat. Bár programozók írni a saját verzióját, a gyakorlatban, az ember azt a gyengén nem kompatibilis változata. Ezen felül, a másik oka - a hatékony végrehajtásának bejáró combinators S. használata itertools funkciók is jelentősen gyorsabb, mint írásban a saját combinators. A szabványos dokumentáció mutató egyenértékű megvalósítások tiszta Python itertools az egyes funkciók. így nincs szükség megismételni őket ebben a cikkben.

Funkciók itertools alapvető - és egyértelműen megnevezett -, hogy lenne értelme importálni összes nevének ezt a modult. felsorolni () függvény. például, hogy létezhet itertools. hanem egy beépített Python 2.3 vagy újabb. Különösen akkor könnyen kifejezni enumerate () szempontjából itertools funkciók:

Nézzünk néhány itertools funkciókat. akik nem használnak más iterátorokat alapul, hanem egyszerűen létrehozhat iterátorokat „a semmiből”. alkalommal () visszatér egy iterátor, amely termel azonos cél több alkalommal; Maga ez a lehetőség nagyon hasznos, de ez igazán szép a túlzott használata xrange () és az index változó egyszerűen ismételje meg a műveletet. Vagyis ahelyett, hogy:

Most már használhatja a semlegesebb:

Ha a második argumentum nem telt az idő (). egyszerűen újra kibocsátja Semmi. ismétlés () függvény hasonló szer (). de határtalan tér vissza ugyanarra a tárgyra. Ez bejáró hasznos ha akár egy hurok van egy független feltétele szünetet. vagy combinators mint izip () és IMAP ().

A count () függvény hasonló a kereszt között ismétlés () és xrange (). A count () visszatér a végtelenségig egymást követő egész szám (kezdve az opcionális argumentum). Tekintettel azonban arra a tényre, hogy a jelenleg count () rendesen nem támogatja az automatikus átalakítás hosszú túlcsordulás, akkor ugyanolyan jól használja tovább xrange (n, sys.maxint) csak nem korlátlan, de a legtöbb célra vezet ugyanaz. Mint ismétlés (). count () különösen hasznos belül más iterátor combinators.

kombinatorikus funkciók

Néhány igazi kombinatorikus funkciók itertools már futólag említik. IFilter (). izip () és imap () viselkednek ahogy azt az ember elvárná, hogy megfelelő szekvencia funkciókat. ifilterfalse () - egy kisegítő funkció, így nem kell megfordítani a predikátum függvény egy lambda a def (és takarít hívás overhead funkciók). De funkcionálisan Definiálhatja ifilterfalse () (kb, figyelmen kívül hagyva a Nincs állítmány), mint:

dropwhile () és takewhile () bejáró részesedése állítmány. Először figyelmen kívül hagyja elemeket, amíg egy állítmányt végre, és kiadja a második, míg az állítmány teljesül. dropwhile () kihagyja meghatározatlan számú kezdeti elemeinek egy iterátor, így lehet kezdeni iterációjával amíg késleltetés után. takewhile () váltja fel azonnal, hanem megszünteti a bejáró, ha az átadott állítmány igaz lesz.

islice () () függvény, sőt, csak a bejáró változatát lista szeletelés. Beállíthatjuk, hogy a start, stop és fokozzák rendszeres szelet. Ha top van megadva, számos olyan elemet mindaddig kiöntöttük, amíg az átvitt iterator eléri az elem. Ez egy másik eset, amikor, ahogy én gondolom javítani lehet a Python - ez lenne a legjobb iterátorokat egyszerűen felismerik szelet, ahogy tartalmazzák (szinonimájaként, ami islice () nem).

Az utóbbi funkció Starmap () - egy kis eltérés a IMAP () (). Ha ezt a funkciót, amelyet mint argumentum kap egy sor átadott argumentumok bejáró kell készítenie hármas megfelelő méretű. Lényegében, ez ugyanaz, mint a IMAP () több iterables telt el, csak egy sor iterables előzőleg egyesítjük izip ().

Több, mint az alapokat

A funkciókat tartalmazza itertools - záloga a jó kezdés. Legalább ösztönzik Python használata és kombinálása iterátoroké. Általában a széles körben elterjedt használata iterátorokat természetesen fontos a jövő Python. De emellett a már felsorolt, vannak más funkciók, amelyek csak javasolni tudom későbbi kiadásaiban ezt a modult. Ezeket fel lehet használni azonnal - persze, ha később benne, a nevek és a felületek eltérhetnek.

rendes iterables használhatja:

Python végrehajtása:

3. lista Alkalmazási példa lánc ()

Azt is kombinálni iterátorokat, vegyítve őket. Beépített szintaxis ugyanezt a sorozatok, de szőni () önmagában is remekül működik véges szekvenciákat. Egy lehetséges megvalósítás az alábbiakban látható (Lai Hetlend Magnus (Magnus Lie Hetland) adtak hasonló funkciót comp.lang.python):

4. lista A kiviteli alak szövése ()

Hadd illusztráljam a viselkedését sző (). mert nem lehet azonnal nyilvánvaló ez a felismerés:

Még azután is, néhány iterátorokat kimerültek, a maradék továbbra is így értékek amíg minden rendelkezésre álló engedett egy bizonyos ponton.

Fogom ajánlani egy másik lehetséges funkció itertools. Megközelítés a problémát ez többnyire kölcsönzött funkcionális programozás. icompose () van egy bizonyos szimmetriát ireduce () a fent tárgyalt. Azonban, ha ireduce () továbbítja funkció (késleltetett) érték szekvencia, és kiadja az egyes eredményeket, icompose () használ sorozata funkciók a visszatérési értéke egyes megelőző funkciók. Téglából ireduce () - az események sorozatát a hosszú életű objektumot. icompose () ehelyett egymást továbbítja az objektum-mutációt előidéző ​​funkciók, amelyek mindegyike visszaad egy új objektumot. Ha az első - meglehetősen hagyományos objektum-orientált módon mutatja események, a második sokkal gyakoribb a funkcionális programozási megközelítés.

Az alábbiakban - egy lehetséges megvalósítási icompose ():

5. lista A kiviteli alak icompose ():

következtetés

Bejárók, fogant, mint lusta szekvenciákat, erőteljes koncepció, amely megnyitja az új stílusok Python programozási. Bár van egy apró különbség a képviselet a bejáró mint adatforrás és annak képviselete egységes módon történjen. Sem módon mutatja önmagában nem szünteti meg a többi, de a második utat nyit a kombinatorikus gyorsírásos manipulálására programozott eseményeket. Kombinatorikus funkciók itertools (és különösen néhány, hogy lehet fejleszteni, mint azok, amelyek azt javaslom) közel van a deklaratív stílus programozás. Véleményem szerint ezek a deklaratív stílusok kevesebb hibalehetőséggel és erősebb.

Letölthető Resources

Kapcsolódó témák