Informatika2-2013/Eloadas Python
259. sor: | 259. sor: | ||
</python> | </python> | ||
− | '''A karakterláncok nem változtatható (immutable) objektumok''', vagyis a műveletek, | + | '''A karakterláncok nem változtatható (immutable) objektumok''', vagyis a műveletek, tagfüggvények alkalmazása után új karakterlánc keletkezik: |
<python> | <python> | ||
>>> a = "aaaa" | >>> a = "aaaa" | ||
517. sor: | 517. sor: | ||
==== Azonossági művelet ==== | ==== Azonossági művelet ==== | ||
+ | |||
+ | Az alábbi példában a és b még azonos, mert ugyanarra az objektumra hivatkoznak, de a c és d már '''nem azonosak''', bár egyenlők: | ||
+ | <python> | ||
+ | >>> a = 2 | ||
+ | >>> b = 2 | ||
+ | >>> a is b | ||
+ | True | ||
+ | >>> c = [1, 2, 3] | ||
+ | >>> d = [1, 2, 3] | ||
+ | >>> c is d | ||
+ | False | ||
+ | >>> c == d | ||
+ | True | ||
+ | </python> | ||
==== Összehasonlító műveletek ==== | ==== Összehasonlító műveletek ==== | ||
+ | |||
+ | Nem csak a számok, de karakterláncok, sorozatok, listák... is összehasonlíthatók (==, !=, <, >, <=, >=): | ||
+ | <python> | ||
+ | >>> a = 23 | ||
+ | >>> b = 56 | ||
+ | >>> a == b | ||
+ | False | ||
+ | >>> a != b | ||
+ | True | ||
+ | >>> a <= b | ||
+ | True | ||
+ | >>> c = "abc" | ||
+ | >>> d = "abcd" | ||
+ | >>> c == d[:3] | ||
+ | True | ||
+ | >>> c < d | ||
+ | True | ||
+ | >>> (2, 1, 3) <= (2, 1, 4) | ||
+ | True | ||
+ | </python> | ||
==== Tagsági műveletek ==== | ==== Tagsági műveletek ==== | ||
+ | |||
+ | in, not in: | ||
+ | <python> | ||
+ | >>> l = [1, 2, "cica"] | ||
+ | >>> 2 in l | ||
+ | True | ||
+ | >>> "macska" not in l | ||
+ | True | ||
+ | >>> "c" in l[2] | ||
+ | True | ||
+ | >>> "ci" in l[2] | ||
+ | True | ||
+ | >>> "ci" in l | ||
+ | False | ||
+ | </python> | ||
+ | |||
==== Logikai műveletek ==== | ==== Logikai műveletek ==== |
A lap 2013. április 9., 11:21-kori változata
Tartalomjegyzék
|
Bevezetés a Python nyelvbe
A Pythont ismerjük a Sage-ből. Különbségek:
- ^ helyett ∗∗, / osztást, // egészosztást jelöl.
- [a..b] helyett range(a,b), vagy xrange(a,b)
- A megszokott, beépített matematikai függvények hiánya (find_root, plot, is_prime).
- Nincsenek szimbolikus változók
A Python egy olyan általános körben használható magas szintű programozási nyelv, aminek az egyik alapelve az olvasható kód írása egy nagyon tiszta szintaxis használatával. 1991-ben alkotta meg Guido Van Rossum.
További jellemzők
- objektum orientált (imperatív, procedurális), funkcionális
- sok beépített modul a fejlesztés megkönnyítésére
- dinamikus típus kezelés
- automatikus memóriakezelés
- többféle megvalósítás (CPython, Jython, IronPython, PyPy, Python for S60)
- open-source a főbb platformokra
Python kód futtatása
A kód futtatható interpreter konzolon belül és külső fájlban tárolva.
- Nyiss egy új file-t pl. a gedit-ben, mentsd el "kerdez.py" néven egy könyvtáradba!
- Írd bele a következő python kódot (ne használj ékezeteket):
s = input("Mondj egy szamot: ") print "Ennel eggyel kisebbet mondtal: ", str(s + 1)
- Mentsd el, és futtasd a scriptedet! (python kerdez.py)
- Most kicsit kiegészítjük a scriptet, hogy tartalmazhasson ékezetes betűket, és hogy kényelmesebben futtatható legyen (a python parancs begépelése nélkül is):
#!/usr/bin/python #coding=UTF-8 s = input("Mondj egy számot: ") print "Ennél eggyel kisebbet mondtál: ", str(s + 1)
- Mentsd el, és adj rá futtatási jogot csak magadnak (
chmod +x kerdez.py
)! - Futtasd így:
kerdez.py
vagy így:./kerdez.py
- A kód második sora lehet ez is:
# -*- coding: utf-8 -*-
Kódolás stílusa
Stílus (code style) a PEP 8 alapján
- használj mindig 4 space-t minden egyes szinthez, de a folytatósort kezd még beljebb,
- a nagyobb kódrészeket tagold üres sorokkal (függvény, osztály, nagyobb kód blokk)
- használj space-t a vesző után és az operátorok mellett
- használj docstring-et és ahol lehet a megjegyzés a saját sorára vonatkozzon
- ahol lehet használj ASCII karakterkódolást
- 79 karakternél ne legyen hosszabb egy sor (elvben 80)
- CamelCase elnevezési konvenciót kövesse az osztályok neve és lower_case_with_underscores a függvények és változók nevei
Érdemes megnézni a Google python code style ajánlását is.
Docstring
A hivatkozás nélküli string elemet szokás használni megjegyzések írására és dokumentálásra.
"""This is a class of example.
TODO: needs implementation.
"""
Első sort nagybetűvel kezdjük és pontal zárjuk. Egy összefoglaló mondat legyen. Majd egy üres sort hagyva részletesen leírhatunk minden funkciót amit az osztály vagy függvény tartalmaz.
Hasznos linkek:
A Python eljárásközpontú (procedurális) programozásának elemei
Adattípusok
Az adatokat többszöri felhasználásra azonosítóval (névvel) láthatjuk el.
Azonosítók
- a név betűvel vagy aláhúzással kezdődhet: [_a-zA-Z]
- a név további karakterei az előbbieken felül számok is lehetnek: [_a-zA-Z0-9]
- elméletileg bármilyen hosszú lehet a név
- név nem lehet foglalt szó
- nagybetü kisbetü érzékeny, tehát a val1 név nem azonos a Val1 névvel
Másképp, Backus–Naur formában leírva:
identifier ::= (letter|"_") (letter | digit | "_")* letter ::= lowercase | uppercase lowercase ::= "a"..."z" uppercase ::= "A"..."Z" digit ::= "0"..."9"
A foglalt szavak:
and del from not while
as elif global or with
assert else if pass yield
break except import print
class exec in raise
continue finally is return
def for lambda try
De ne használjuk a Python beépített neveinek, függvényeinek, kivételeinek neveit sem. Ezek megkaphatók a dir(__builtins__)
paranccsal:
>>> dir() ['__builtins__', '__doc__', '__name__', '__package__'] >>> dir(__builtins__) ['ArithmeticError', 'AssertionError', ......
Egészszerű adattípusok: egész (int, long), logikai (bool)
int (egész) és hosszú egész (long)
>>> a = 12 >>> b = 0b011101 >>> c = 0o3701 >>> d = 0xff0c >>> a, b, c, d (12, 29, 1985, 65292) >>> e = 22222222222222222222222222222222222222222 >>> e 22222222222222222222222222222222222222222L >>> type(a), type(b), type(e) (<type 'int'>, <type 'int'>, <type 'long'>)
Műveletek egészekkel: +, -, *, / (float eredményt ad), //, % (maradék), **, abs, pow, round, | (OR butenként), ^ (XOR bitenként), & (AND bitenként), <<, >> (eltolás bitenként), ~ (bitenkénti NOT)
Logikai (bool) típus:
Logikai értékek: False (0), True (nem 0)
Logikai műveletek: and, or, not
>>> True and False False >>> 1 and 0 0 >>> 3 and 0 0 >>> 3 or 1 3 >>> 1 or 3 1 >>> not 67 False >>> not 0 True
Beépített lebegőpontos típusok (float, complex)
A műveletek eredménye NaN (not a number) és infinity is lehet!
Lebegőpontos szám megadása:
>>> 2.3, -1.2e3, -1.2e-2 (2.2999999999999998, -1200.0, -0.012)
Matematikai függvények:
import math
után. Ld. [1]
Komplex szám imaginárius része után j betű, de * nincs! Komplex jellemzői (attribute) a real és az imag, tagfüggvénye (method) conjugate():
>>> z = 3.1 + 2.2j >>> z (3.1000000000000001+2.2000000000000002j) >>> z.real 3.1000000000000001 >>> z.imag 2.2000000000000002 >>> z.conjugate() (3.1000000000000001-2.2000000000000002j)
Karakterláncok (str)
A karakterláncok megadása: "...", '...' vagy """...""" módon történhet:
>>> a="""itt 'ez' meg "az" van""" >>> a 'itt \'ez\' meg "az" van' >>> print a itt 'ez' meg "az" van >>> type(a) <type 'str'> >>> c = 'aa\nbb' >>> c 'aa\nbb' >>> print c aa bb >>> d = r'aa\nbb' # az r betű után minden karakter magát jelenti >>> d 'aa\\nbb' >>> print d aa\nbb
Védőkódok (escape characters): \ (folytatás új sorban), \\ (\), \' ('), \" ("), \n (új sor), \t (tab). Ha a karakterlánc elé r betűt írunk, a védőkódok nem érvényesek.
Műveletek karakterláncokkal: indexelés és szeletelés:
lánc[sorszám] lánc[kezdet:vég] lánc[kezdet:vég:lépés]
továbbá az + (összefűzés) és a * (többszörözés) műveletek:
>>> a = "ho" >>> b = "rgasz" >>> 3*a + b 'hohohorgasz' >>> c = _ # _ az előző eredmény >>> c 'hohohorgasz' >>> c[:2]+c[6:] 'horgasz' >>> c[1:7:2] 'ooo' >>> c[1:6:2] 'ooo' >>> c[-1::-1] 'zsagrohohoh' >>> c[-3:4:-1] 'agro'
Tagfüggvények: részletesen lásd [2]. Folytatva az előző példát:
>>> c.capitalize() 'Hohohorgasz' >>> c.upper() 'HOHOHORGASZ' >>> c.index('o') 1 >>> c.count('o') 3
A karakterláncok nem változtatható (immutable) objektumok, vagyis a műveletek, tagfüggvények alkalmazása után új karakterlánc keletkezik:
>>> a = "aaaa" >>> a[1] = b Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'str' object does not support item assignment
Objektumhivatkozások
Az értékadás (=) esetén valójában objektumhivatkozás történik, azaz az egyenlőség bal oldalán álló névhez egy hivatkozás kapcsolódik, mely az egyenlőség jobb oldalán álló objektumra mutat. Ez érthetővé teszi a következő kódot:
>>> a = 1 >>> b = a >>> a = 2 >>> a 2 >>> b 1
A Python dinamikusan típusos nyelv, azaz az objektum, amire egy objektumhivatkozás mutat, lecserélhető egy más típusú objektumra (nem kell a változók típusát deklarálni).
>>> a = 1 >>> type(a) <type 'int'> >>> a = "b" >>> type(a) <type 'str'>
Gyűjteményes adattípusok
Sorozatszerű típusok: str, list, tuple
Tuladonságaik: bejárhatók, in, len(), []
Sorozat (tuple) változtathatatlan (immutable), mint a karakterlánc, műveletei: szeletelés [], összefűzés (+), szorzás (*), összehasonlítás, tagsági viszony (in, not in)
>>> t = () >>> t () >>> t = 1, 5, 5, 5, 3 # itt elhagyható a zárójel >>> t (1, 5, 5, 5, 3) >>> t[1] 5 >>> t.index(3) 4 >>> t.count(5) 3
lista - változtatható (mutable)
[3]
>>> l[1:4:2] = [7, 8] >>> l [1, 7, 3, 8, 5] >>> l.remove(7); l [1, 3, 8, 5] >>> l.reverse(); l [5, 8, 3, 1] >>> l.append(99); l [5, 8, 3, 1, 99] >>> l += [55, 66] >>> l [5, 8, 3, 1, 99, 55, 66] >>> l.pop() 66 >>> l [5, 8, 3, 1, 99, 55]
Halmaztípusok: halmaz (set)
Lásd [4]
>>> s = set([5,6,7,8,6]) >>> s set([8, 5, 6, 7]) >>> s2 = set() >>> s2 set([]) >>> s2 = s.copy() >>> s2 set([8, 5, 6, 7]) >>> s2.add(6) >>> s2.add(11) >>> s2 set([8, 11, 5, 6, 7]) >>> s2.difference(s) set([11]) >>> s2.discard(11) >>> s2.difference(s) set([]) >>> s2.intersection(s) set([8, 5, 6, 7]) >>> s2.update([5,4,3]) >>> s2 set([3, 4, 5, 6, 7, 8]) >>> s2.discard(2) >>> s2 set([3, 4, 5, 6, 7, 8]) >>> s2.remove(3) >>> s2 set([4, 5, 6, 7, 8]) >>> s2.remove(3) Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 3 >>> s set([8, 5, 6, 7]) >>> s.union(set([56,5])) set([56, 5, 6, 7, 8]) >>> s set([8, 5, 6, 7]) >>> s2 set([4, 5, 6, 7, 8]) >>> s.clear() >>> s set([])
Megfeleltetési típusok: szótár (dict)
Lásd [5]
>>> d = dict() >>> d {} >>> d = {} >>> d {} >>> d = {'fn':'Marci', 'ln':'Pala', 2:89} >>> d {'ln': 'Pala', 2: 89, 'fn': 'Marci'} >>> d[2] 89 >>> d['ln'] 'Pala' >>> d2 = d.copy() >>> d2 {'ln': 'Pala', 2: 89, 'fn': 'Marci'} >>> d2[2] = 8 >>> d2 {'ln': 'Pala', 2: 8, 'fn': 'Marci'} >>> d {'ln': 'Pala', 2: 89, 'fn': 'Marci'} >>> d.update([("t",3),('b',6)]) >>> d {'ln': 'Pala', 2: 89, 'b': 6, 't': 3, 'fn': 'Marci'} >>> d2 {'ln': 'Pala', 2: 8, 'fn': 'Marci'} >>> d.values() ['Pala', 89, 6, 3, 'Marci'] >>> d.pop('b') 6 >>> d {'ln': 'Pala', 2: 89, 't': 3, 'fn': 'Marci'} >>> d.keys() ['ln', 2, 't', 'fn'] >>> d.items() [('ln', 'Pala'), (2, 89), ('t', 3), ('fn', 'Marci')] >>> d.clear() >>> d {} >>> len(d) 0 >>> d2 {'ln': 'Pala', 2: 8, 'fn': 'Marci'}
Listaértelmezések (list comprehension)
Rövid listák létrehozásának egyszerű módja. Általános alakja:
[expression for expr in sequence1 if condition1 for expr2 in sequence2 if condition2 ... for exprN in sequenceN if conditionN]
Kis programrészek helyettesíthetők vele. Például soroljuk fel a szökőéveket 1890 és 1915 között.
szoko = [] for ev in range(1890, 1922): if (ev%4 == 0 and ev%100 != 0) or (ev%400 == 0): szoko.append(ev) print szoko [1892, 1896, 1904, 1908, 1912, 1916, 1920]
Lépésenként egyre összetettebb listaértelmezéssel állítsuk elő ugyanezt:
>>> szoko = [ev for ev in range(1890, 1915)] >>> szoko # ez még az összes év [1890, 1891, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1914] >>> szoko = [ev for ev in range(1890, 1915) if ev%4 == 0] >>> szoko # ez a 4-gyel osztható évek listája [1892, 1896, 1900, 1904, 1908, 1912] >>> szoko = [ev for ev in range(1890, 1915) if (ev%4 == 0 and ev%100 != 0) or ev%400 == 0] >>> szoko [1892, 1896, 1904, 1908, 1912]
Egy hasonló feladat: Hányféleképp lehet nyolc királynőt föltenni egy sakktáblára, hogy semelyik kettő ne üsse egymást?
Az ilyen bástyaelhelyezések száma 8! = 40320. A királynők azonban átlósan is üthetik egymást. Az i-edik és j-edik sorban lévő királynő pontosan akkor üti egymást, ha abs(i - j) != abs(x[i] - x[j]). A permutációk listázásához töltsük be az itertools csomag permutations függvényét, mely a for ciklus minden ciklusában ad egy övetkező permutációt, amíg a végére nem ér. Így a megoldás:
from itertools import permutations for x in permutations(range(8)): if all([i == j or abs(i - j) != abs(x[i] - x[j]) for i in range(8) for j in range(8)]): print x
Gyűjtemények másolása (sekély és mély másolás)
Az értékadás (=) csak objektumhivatkozással jár, nem történik adatmásolás. Ennek következtében egy y = x
parancs után, ahol x gyűjteményes adattípus, az y ugyanarra az objektumra fog mutatni. Így ha megváltoztatjuk x-et vagy y-t, változik a másik is. Az objektumhivatkozások megtörténhetnek egy szinttel mélyebben is, a (z = x[:]
kód esetén az x elemeire mutató hivatkozások másolódnak, de ekkor sem jön létre a teljes objektumról másolat. Ezt hívjuk
sekély másolásnak (shallow copy).
>>> x = [1, 2, ["a","b"]] >>> y = x >>> z = x[:] >>> y[0] = 0 >>> x, y, z ([0, 2, ['a', 'b']], [0, 2, ['a', 'b']], [1, 2, ['a', 'b']]) >>> z[0] = 5 >>> x, y, z ([0, 2, ['a', 'b']], [0, 2, ['a', 'b']], [5, 2, ['a', 'b']]) >>> x[2][0] = "X" >>> x, y, z ([0, 2, ['X', 'b']], [0, 2, ['X', 'b']], [5, 2, ['X', 'b']])
Mély másolás (deep copy), amikor valóban új példány keletkezik az objektumból:
import copy w = copy.deepcopy(x)
Műveletek, operátorok
Logikai értéket visszaadó műveletek
Azonossági művelet
Az alábbi példában a és b még azonos, mert ugyanarra az objektumra hivatkoznak, de a c és d már nem azonosak, bár egyenlők:
>>> a = 2 >>> b = 2 >>> a is b True >>> c = [1, 2, 3] >>> d = [1, 2, 3] >>> c is d False >>> c == d True
Összehasonlító műveletek
Nem csak a számok, de karakterláncok, sorozatok, listák... is összehasonlíthatók (==, !=, <, >, <=, >=):
>>> a = 23 >>> b = 56 >>> a == b False >>> a != b True >>> a <= b True >>> c = "abc" >>> d = "abcd" >>> c == d[:3] True >>> c < d True >>> (2, 1, 3) <= (2, 1, 4) True
Tagsági műveletek
in, not in:
>>> l = [1, 2, "cica"] >>> 2 in l True >>> "macska" not in l True >>> "c" in l[2] True >>> "ci" in l[2] True >>> "ci" in l False
Logikai műveletek
and, or, not (ld. fönt)
Operátorok precedenciája
Az operátorok között, mint a matematikában itt is, van precedencia sorrend:
Operator | Description |
---|---|
lambda | Lambda expression |
if – else | Conditional expression |
or | Boolean OR |
and | Boolean AND |
not x | Boolean NOT |
in, not in, is, is not, <, <=, >, >=, <>, !=, == | Comparisons, identity test, including membership test |
| | Bitwise OR |
^ | Bitwise XOR |
& | Bitwise AND |
<<, >> | Shifts |
+, -
|
Addition and subtraction |
*, //, /, % | Multiplication, division, remainder |
+x, -x, ~x
|
Positive, negative, bitwise not |
** | Exponentiation |
x[index], x[index:index], x(arguments...), x.attribute | Subscription, slicing, call, attribute reference |
(expressions...), [expressions...], {key:datum...}, `expressions...` | Binding or tuple display, list display, dictionary display, string conversion |
A sage, python a kifejezéseket balról jobbra értékeli ki, kivéve az értékadásnál, amikor előbb a jobb oldalt értékeli ki, majd a bal oldalt. Pl. a logikai kifejezés elemeit ha mar felesleges nem értékeli ki.