2.30. Lyhennetyt muodostimet#

Lyhennetty muodostin rakentaa uuden listan, joukon, sanakirjan tai generaattorin olemassa olevasta iteroitavasta yhdellä lausekkeella. Se korvaa yleisen mallin, jossa aloitetaan tyhjästä säiliöstä ja lisätään alkioita silmukassa.

2.30.1. Listamuodostimet#

squares = [x * x for x in range(5)]
print(squares)

Tuloste:

[0, 1, 4, 9, 16]

Sama silmukka auki kirjoitettuna:

squares = []
for x in range(5):
    squares.append(x * x)

Muodostinmuoto on yksi lauseke, joka rakentaa listan paikallaan. Ei ole squares = []-riviä eikä .append-kutsua – tulos on muodostimen arvo.

The expression "[f(x) for x in xs if cond]" annotated: the leading expression is the result, the for clause names the loop variable, the if clause filters which items are kept.

Alkupään lauseke tuottaa jokaisen alkion; for-lause nimeää silmukkamuuttujan; valinnainen if suodattaa alkioita pois.#

2.30.2. Suodatus if-lauseella#

Valinnainen if-lause säilyttää vain alkiot, jotka täsmäävät:

evens = [x for x in range(10) if x % 2 == 0]
print(evens)

Tuloste:

[0, 2, 4, 6, 8]

Suodatin suoritetaan ennen alkupään lauseketta – x % 2 == 0 tarkistetaan ensin; vain täsmäävät arvot päätyvät muuttujaan x tulostetta varten.

2.30.3. Sanakirja- ja joukkomuodostimet#

Sama muoto toimii sanakirja- ja joukkoliteraalien kanssa.

Sanakirjamuodostimessa on key: value -pari ennen for-osaa:

squares = {x: x * x for x in range(5)}
print(squares)

Tuloste:

{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

Joukkomuodostin käyttää aaltosulkeita ja yhtä lauseketta:

unique_lengths = {len(w) for w in ["a", "bb", "c", "bb"]}
print(unique_lengths)

Tuloste:

{1, 2}

2.30.4. Generaattorilausekkeet#

Tavalliset sulkeet tuottavat generaattorilausekkeen listan sijaan. Arvot lasketaan yksi kerrallaan tarpeen mukaan:

total = sum(x * x for x in range(1000))

Miljoonan alkion listaa ei koskaan rakenneta. Arvot virtaavat yksitellen sum()-funktioon, joka laskee ne yhteen ja hylkää kunkin sitä mukaa.

Generaattorilausekkeet ovat oikea valinta, kun syötät arvoja pelkistävään funktioon (sum(), max(), any(), all()) tai mihin tahansa muuhun iteraattoria kuluttavaan koodiin – ne säästävät muistin, jonka vastaava lista olisi käyttänyt.

2.30.5. Milloin lyhennettyä muodostinta ei kannata käyttää#

Muodostimet ovat tiiviitä mutta eivät aina selkeämpiä. Tartu tavalliseen for-silmukkaan kun:

  • Runko tarvitsee enemmän kuin yhden lauseen (muodostimeen mahtuu täsmälleen yksi lauseke).

  • Rungolla on sivuvaikutuksia (tulostus, tiedostoon kirjoittaminen) – muodostimet ovat kokoelman rakentamista varten, eivät toimintojen suorittamista varten.

  • Suodattimessa tai muunnoksessa on niin monta osaa, ettei muodostin enää luetu vasemmalta oikealle.