Hlavní navigace

Létající cirkus (3)

Jan Švec

V dalším pokračování našeho povídání o jazyce Python se budeme věnovat logickým výrazům a probereme si nejdůležitější logické operátory.

Logické výrazy

Každý výraz jazyka Python může být zároveň i logickým výrazem. Podobně jako v jazyce C zde neexistuje žádný speciální typ určený pro logické proměnné. I tady se místo něho může používat obyčejný integer (nulová hodnota je false, cokoli jiného true). Ale i výrazy jiných typů mohou být vyhodnoceny jako logický výraz. Například prázdná sekvence má hodnotu false, hodnota None je vyhodnocena jako false, hodnota Ellipsis true atd. Blíže se o tomto problému zmiňuje dokumentace k jazyku.

V Pythonu, stejně jako v céčku a jiných jazycích, můžeme nalézt tyto relační operátory: <, >, ==, !=, >=, <=. Mimo nich existuje ještě <>, ale samotní autoři doporučují místo něj raději používat ekvivalentní !=. Každé porovnání vrací pouze hodnoty 1 (true) nebo 0 (false). Python umožňuje zřetězení operátorů, zápis a < b < c je tady ekvivalentní zápisu a < b and b < c. V prvním případě se ale výraz b vyhodnotí pouze jednou, kdežto ve druhém dvakrát. Lze zapsat i a < b > c, pak tento matematický „patvar“ vede k zápisu a < b and b > c.

Python umožňuje porovnávat nejen čísla, ale i řetězce (i unicodové) a obecně jakoukékoli jiné sekvence. Porovnávání sekvencí se děje lexikograficky (tj. nejprve nultý prvek s nultým, poté první s prvním atd., dokud není nalezen první rozdíl nebo jedna ze sekvencí neskončí). Lahůdkou je možnost porovnávaní asociativních polí. Interpret si nejprve převede asociativní pole na sekvenci z prvků (klíč, hodnota), kterou si setřídí, a následně obě sekvence porovná. Jazyk dokonce umožňuje i porovnávání různých typů. Výsledek takového porovnání záleží čistě na vůli interpretu, ale je VŽDY stejný, takže třeba číslo je vždy menší než seznam, ten je zase menší než řetězec atd. Čísla různých typů se nejprve převedou na společný typ a pak se teprve porovnají. Pro bližší informace viz. dokumentace k jazyku.

>>> (1, 2, 3) < (1, 2, 4)
1
>>> [1, 2, 3] < [1, 2, 4]
1
>>> 'Brezen' < 'Cerven' < 'Cervenec'
1
>>> (1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4)
1
>>> 1 == 1.0
1

Logické operátory, jak je známe z jazyka C, bychom hledali marně. Python pro logický součin, součet a negaci používá místo symbolů &&, || a ! slova and, or a not. Důvod je prostý: opomenutím jednoho „endu“ jsme dostali bitový součin, a ne logický. Ze stejných důvodů Python také nedovoluje použití přiřazení ve výrazu. Nejednoho začátečníka v C zaskočila záměna = a == například v podmínce if. Programátor v Pythonu si prostě musí zvyknout na to, že funkčnost někdy musela ustoupit estetice a přehlednosti.

Operátory and a or pracují odlišně od jiných jazyků. Zde výsledek nemusí být jen 1 nebo 0, ale může mít obecně jakoukoli hodnotu a typ:

  • Při vyhodnocování výrazu x and y se nejprve vyhodnotí výraz x, je-li false, je vrácena jeho hodnota, jinak se vyhodnotí výraz y a vrátí se výsledek výrazy y:
    >>> 1 and 4
        4
        >>> 0 and 4
        0
    
  • Při vyhodnocování výrazu x or y se nejprve vyhodnotí výraz x, je-li true, je vrácena jeho hodnota, jinak se vyhodnotí výraz y a vrátí se výsledek výrazu y:
    >>> 1 or 4
        1
        >>> 0 or 4
        4
    

Na první pohled chování stejné jako v jiných jazycích, ale … Python totiž dokáže vyhodnotit libovolný výraz jako logický (viz. začátek dnešního dílu) a výše zmíněné hodnoty se přímo nabízejí i k jinému způsobu použití, než jen k vytváření logických výrazů, třeba k dosazení implicitní hodnoty:

>>> answer = raw_input('Zadejte text: ')                   (1)
                                                           (2)
>>> print 'Zadali jste ' + (answer or 'prazdny retezec')   (3)
Zadali jste prazdny retezec

V Pythonu můžeme, stejně jako v jiných jazycích, ovlivňovat prioritu operátorů pomocí závorek. To jsme provedli i na řádku (3), jelikož operátor + má vyšší prioritu než logický operátor or. O prioritě operátorů se více zmiňuje dokumentace jazyka.

Další operátory, které nemají v céčku obdobu, jsou in a not in. Ty mají dva operandy m, n. Operátor in testuje, je-li m prvkem sekvence n, not in je je jeho pravým opakem.

>>> 'l' in 'linux'
1
>>> 1 in (2, 3, 4, 5)
0

Na konec povídání o operátorech se ještě zmiňme o operátoru is. Ten testuje, jsou-li jeho dva operandy jedním a týmž objektem. Vytváříte-li nový objekt proměnného typu, je vždy v paměti vytvořen objekt nový, ne tak při vytváření objektu neměnného typu. Zde již interpret MŮŽE (ale NEMUSÍ) použít nějakou předchozí instanci v paměti. Je jen na jeho libovůli, učiní-li tak, nebo ne.

>>> a = []
>>> b = []
>>> a is b
0
>>> a = ()
>>> b = ()
>>> a is b
1             # MŮŽE BÝT I 0, ZÁLEŽÍ NA INTERPRETRU

Příště

V dalším povídání o jazyce Python se budeme věnovat proměnným, prostorům jmen a uživatelským funkcím. Ukážeme si, jak deklarovat globální proměnné, jak odstranit proměnnou z prostředí a jak definovat a volat uživatelské funkce.

Našli jste v článku chybu?