3. Nieformalne wprowadzenie do Pythona

W nadchodzących przykładach wejście i wyjście są rozróżniane przez obecność lub nieobecność promptów (>>> i ): aby powtórzyć przykład, musisz wpisać wszystko po prompcie, kiedy prompt jest widoczny; linie, które nie zaczynają się promptem są wyjściem z interpretera. Zwróć uwagę, że prompt drugiego rzędu z pustą linią w przykładzie oznacza, że musisz wpisać pustą linię; używa się tego do zakończenia wielo-liniowej komendy.

Wiele przykładów w tym manualu, także tych wpisywanych w interaktywnej konsoli, zawiera komentarze. Komentarze w Pythonie zaczynają się znakiem kratki # i ciągną się do końca fizycznej linii. Komentarz może pojawić się na początku linii, po wiodących spacjach lub kodzie, lecz nie może być zawarty w literale ciągu znaków. Znak kratki w ciągu znaków jest po prostu znakiem kratki. Jako że komentarze mają wyjaśniać kod i nie są interpretowane przez Pythona, można je ominąć przy wpisywaniu przykładów.

Trochę przykładów:

# this is the first comment
spam = 1  # and this is the second comment
          # ... and now a third!
text = "# This is not a comment because it's inside quotes."

3.1. Używanie Pythona jako kalkulatora

Wypróbujmy parę prostych poleceń Pythona. Uruchom interpreter i poczekaj na pojawienie się pierwszego znaku zachęty >>>. (Nie powinno to zająć dużo czasu.)

3.1.1. Liczby

Interpreter działa jak prosty kalkulator: można wpisać do niego wyrażenie, a on wypisze jego wartość. Składnia wyrażenia jest prosta: operatory +, -, * i / działają jak w większości innych języków programowania (na przykład Pascal lub C); nawiasów (()) można użyć do grupowania. Na przykład:

>>> 2 + 2
4
>>> 50 - 5*6
20
>>> (50 - 5*6) / 4
5.0
>>> 8 / 5  # division always returns a floating point number
1.6

Liczby całkowite (np. 2, 4, 20) są typu int, te z częścią ułamkową (np. 5.0, 1.6) są typu float. Więcej o typach numerycznych dowiemy się więcej później w tym tutorialu.

Dzielenie (/) zawsze zwraca liczbę zmiennoprzecinkową. Aby zrobić dzielenie całkowite i uzyskać wynik całkowity (pomijając część ułamkową) możesz użyć operatora //; aby obliczyć resztę możesz użyć %:

>>> 17 / 3  # classic division returns a float
5.666666666666667
>>>
>>> 17 // 3  # floor division discards the fractional part
5
>>> 17 % 3  # the % operator returns the remainder of the division
2
>>> 5 * 3 + 2  # floored quotient * divisor + remainder
17

W Pythonie możesz użyć operatora **, aby obliczać potęgi 1:

>>> 5 ** 2  # 5 squared
25
>>> 2 ** 7  # 2 to the power of 7
128

Znak równości (=) jest używany do przypisania wartości do zmiennej. Przypisanie do zmiennej nie jest wypisywane przez interpreter:

>>> width = 20
>>> height = 5 * 9
>>> width * height
900

Jeśli zmienna nie jest „zdefiniowana” (nie ma przypisanej wartości), próba jej użycia spowoduje błąd:

>>> n  # try to access an undefined variable
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'n' is not defined

Python implementuje w pełni arytmetykę zmiennoprzecinkową; operatory z operandami typów mieszanych przekształcają operandy całkowite w zmiennoprzecinkowe:

>>> 4 * 3.75 - 1
14.0

W trybie interaktywnym ostatnie wyświetlone wyrażenie jest przypisywane do zmiennej _. Dzięki temu kiedy używasz Pythona jako biurkowego kalkulatora, jest nieco prościej kontynuować obliczenia, na przykład:

>>> tax = 12.5 / 100
>>> price = 100.50
>>> price * tax
12.5625
>>> price + _
113.0625
>>> round(_, 2)
113.06

Ta zmienna powinna być traktowana przez użytkownika jako tylko-do-odczytu. Nie przypisuj wprost do niej wartości — stworzyłbyś niezależną zmienną lokalną o tej samej nazwie maskując wbudowaną zmienną z jej magicznym zachowaniem.

Oprócz int i float, Python wspiera inne typy liczb, takie jak Decimal i Fraction. Python ma też wbudowane wsparcie dla liczb złożonych i używa sufiksów j lub J do wskazania części urojonej (np. 3+5j).

3.1.2. Ciągi znaków

Oprócz liczb Python może również manipulować ciągami znaków, które można wyrazić na parę sposobów. Mogą one być objęte pojedynczym ('…') lub podwójnym cudzysłowem ("…") z tym samym efektem 2. \ można użyć, aby zapobiec domyślnej interpretacji znaku cudzysłowu:

>>> 'spam eggs'  # single quotes
'spam eggs'
>>> 'doesn\'t'  # use \' to escape the single quote...
"doesn't"
>>> "doesn't"  # ...or use double quotes instead
"doesn't"
>>> '"Yes," they said.'
'"Yes," they said.'
>>> "\"Yes,\" they said."
'"Yes," they said.'
>>> '"Isn\'t," they said.'
'"Isn\'t," they said.'

W interaktywnym interpreterze wyjściowy ciąg znaków jest otoczony cudzysłowem a znaki specjalne są „uwolnione” ukośnikami wstecznymi. Mimo że może czasem wyglądać inaczej niż wejściowy ciąg znaków (cudzysłów okalający mógł się zmienić), te dwa ciągi znaków są równoważne. Ciąg znaków objęty jest podwójnym cudzysłowem, jeśli zawiera tylko pojedyncze cudzysłowy i nie zawiera podwójnych, w przeciwnym wypadku objęty jest pojedynczym. Funkcja print() produkuje bardziej czytelne wyście, omijając okalający cudzysłów i drukując „uwolnione” i specjalne znaki:

>>> '"Isn\'t," they said.'
'"Isn\'t," they said.'
>>> print('"Isn\'t," they said.')
"Isn't," they said.
>>> s = 'First line.\nSecond line.'  # \n means newline
>>> s  # without print(), \n is included in the output
'First line.\nSecond line.'
>>> print(s)  # with print(), \n produces a new line
First line.
Second line.

Jeśli nie chcesz, aby znaki poprzedzone \ były interpretowane jako znaki specjalne, możesz użyć surowych ciągów znaków dodając r przed pierwszym cudzysłowem:

>>> print('C:\some\name')  # here \n means newline!
C:\some
ame
>>> print(r'C:\some\name')  # note the r before the quote
C:\some\name

Literały ciągów znaków mogą mieć wiele linii. Można je uzyskać używając potrójnych cudzysłowów: """…""" lub '''…'''. Końce linii są automatycznie zawarte w ciągu znaków, ale można tego uniknąć dodając \ na końcu linii. Następujący przykład:

print("""\
Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to
""")

produkuje następujące wyjście (zwróć uwagę, że nie ma pierwszej nowej linii):

Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to

Ciągi mogą być konkatenowane (sklejane) operatorem + i powtarzane przy użyciu *:

>>> # 3 times 'un', followed by 'ium'
>>> 3 * 'un' + 'ium'
'unununium'

Dwa lub więcej literałów ciągów (czyli te zawarte w cudzysłowach) obok siebie są automatycznie konkatenowane.

>>> 'Py' 'thon'
'Python'

To zachowanie jest szczególnie przydatne, gdy chcesz łamać długie ciągi:

>>> text = ('Put several strings within parentheses '
...         'to have them joined together.')
>>> text
'Put several strings within parentheses to have them joined together.'

Jednak działa tylko dla literałów, nie dla zmiennych lub wyrażeń:

>>> prefix = 'Py'
>>> prefix 'thon'  # can't concatenate a variable and a string literal
  File "<stdin>", line 1
    prefix 'thon'
                ^
SyntaxError: invalid syntax
>>> ('un' * 3) 'ium'
  File "<stdin>", line 1
    ('un' * 3) 'ium'
                   ^
SyntaxError: invalid syntax

Jeśli chcesz skonkatenować zmienne lub zmienną i literał, użyj +:

>>> prefix + 'thon'
'Python'

Ciągi znaków mogą być indeksowane. Pierwszy znak ma indeks 0. Nie ma osobnego typu znakowego; znak jest po prostu ciągiem znaków o długości jeden:

>>> word = 'Python'
>>> word[0]  # character in position 0
'P'
>>> word[5]  # character in position 5
'n'

Indeksy mogą być też liczbami ujemnymi, aby zacząć odliczać od prawej:

>>> word[-1]  # last character
'n'
>>> word[-2]  # second-last character
'o'
>>> word[-6]
'P'

Zwróć uwagę, że jako -0 to to samo co 0, ujemne indeksy zaczynają się od -1.

Oprócz indeksowania, dostępne jest także wykrawanie (ang. slicing). Indeksowania używamy, aby uzyskać pojedyncze znaki, wykrawanie pozwala uzyskać podciąg (ang. substring):

>>> word[0:2]  # characters from position 0 (included) to 2 (excluded)
'Py'
>>> word[2:5]  # characters from position 2 (included) to 5 (excluded)
'tho'

Zwróć uwagę, że początkowy indeks wchodzi w skład podciągu, a końcowy nie. W ten sposób s[:i] + s[i:] jest zawsze równe s:

>>> word[:2] + word[2:]
'Python'
>>> word[:4] + word[4:]
'Python'

Indeksy wykrawania mają przydatne wartości domyślne; pominięty pierwszy indeks domyślnie jest zerem, pominięty drugi indeks domyślnie ma wartość długości wykrawanego ciągu.

>>> word[:2]   # character from the beginning to position 2 (excluded)
'Py'
>>> word[4:]   # characters from position 4 (included) to the end
'on'
>>> word[-2:]  # characters from the second-last (included) to the end
'on'

Sposobem na zapamiętanie, jak działa wykrawanie, to myślenie o indeksach wskazujących pomiędzy znakami, z lewą krawędzią pierwszego znaku numerowaną 0. Wtedy prawa krawędź ostatniego znaku ciągu o długości n ma indeks n, na przykład:

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1

W pierwszym wierszu liczb są pozycje indeksów od 0 do 6 w ciągu. W drugim wierszu odpowiadające im indeksy ujemne. Slice od i do j składa się ze wszystkich znaków pomiędzy krawędziami oznaczonymi kolejno i i j.

Dla nieujemnych indeksów długość slice’a to różnica indeksów, jeśli oba mieszczą się w zakresie. Na przykład długość word[1:3] to 2.

Próba użycia za dużego indeksu skończy się błędem:

>>> word[42]  # the word only has 6 characters
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: string index out of range

Jednak indeksy wykrawania poza zakresem są obsłużone bezpiecznie przy wykrawaniu:

>>> word[4:42]
'on'
>>> word[42:]
''

Ciągi znaków Pythona nie mogą być zmieniane — są niemutowalne. W związku z tym przypisywanie wartości do indeksowanej pozycji w ciągu spowoduje błąd:

>>> word[0] = 'J'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
>>> word[2:] = 'py'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

Jeśli potrzebujesz innego ciągu znaków, powinieneś(-nnaś) stworzyć nowy:

>>> 'J' + word[1:]
'Jython'
>>> word[:2] + 'py'
'Pypy'

Wbudowana funkcja len() zwraca długość ciągu:

>>> s = 'supercalifragilisticexpialidocious'
>>> len(s)
34

Zobacz także

Text Sequence Type — str

Ciągi znaków są przykładami typów sekwencyjnych i obsługują wspólne operacje wspierane przez takie typy.

String Methods

Ciągi znaków wspierają dużą liczbę metod do podstawowych przekształceń i wyszukiwania.

Formatted string literals

Literały ciągów znaków z osadzonymi wyrażeniami.

Format String Syntax

Informacje o formatowaniu ciągów znaków przy użyciu str.format().

printf-style String Formatting

Stare operacje formatowania, wywoływane gdy ciągi znaków są lewymi operandami operatora % są opisane tutaj bardziej szczegółowo.

3.1.3. Listy

Python ma kilka złożonych typów danych, używanych do grupowania różnych wartości. Najbardziej wszechstronnym jest lista, która może zostać zapisana jako lista wartości (elementów) rozdzielonych przecinkami ujęta w nawiasy kwadratowe. Listy mogą zawierać elementy różnych typów, ale zazwyczaj wszystkie elementy mają ten sam typ.

>>> squares = [1, 4, 9, 16, 25]
>>> squares
[1, 4, 9, 16, 25]

Tak jak ciągi znaków (i wszystkie inne wbudowane typy sekwencyjne), do elementów list można odwoływać się przez indeksy oraz można z nich „wykrawać”:

>>> squares[0]  # indexing returns the item
1
>>> squares[-1]
25
>>> squares[-3:]  # slicing returns a new list
[9, 16, 25]

Wszystkie operacje wykrawania zwracają nową listę zawierającą żądane elementy. Następujący slice więc zwraca płytką kopię listy:

>>> squares[:]
[1, 4, 9, 16, 25]

Listy wspierają też operacje takie jak konkatenacja:

>>> squares + [36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

W przeciwieństwie do ciągów znaków, które są niemutowalne, listy są typem mutowalnym, w szczególności można zmieniać ich treść:

>>> cubes = [1, 8, 27, 65, 125]  # something's wrong here
>>> 4 ** 3  # the cube of 4 is 64, not 65!
64
>>> cubes[3] = 64  # replace the wrong value
>>> cubes
[1, 8, 27, 64, 125]

Można również dodawać nowe elementy na końcu listy, przez użycie metody (dowiemy się więcej o metodach później) append():

>>> cubes.append(216)  # add the cube of 6
>>> cubes.append(7 ** 3)  # and the cube of 7
>>> cubes
[1, 8, 27, 64, 125, 216, 343]

Możliwe jest również przypisywanie do slice’ów. Może to zmienić rozmiar listy lub zupełnie ją wyczyścić:

>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> letters
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> # replace some values
>>> letters[2:5] = ['C', 'D', 'E']
>>> letters
['a', 'b', 'C', 'D', 'E', 'f', 'g']
>>> # now remove them
>>> letters[2:5] = []
>>> letters
['a', 'b', 'f', 'g']
>>> # clear the list by replacing all the elements with an empty list
>>> letters[:] = []
>>> letters
[]

Wbudowana funkcja len() ma również zastosowanie do list:

>>> letters = ['a', 'b', 'c', 'd']
>>> len(letters)
4

Można zagnieżdżać listy (tworzyć listy zawierające inne listy), na przykład:

>>> a = ['a', 'b', 'c']
>>> n = [1, 2, 3]
>>> x = [a, n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]]
>>> x[0]
['a', 'b', 'c']
>>> x[0][1]
'b'

3.2. Pierwsze kroki do programowania

Oczywiście możemy używać Pythona do zadań bardziej skomplikowanych niż dodawanie dwóch do dwóch. Na przykład możemy napisać początkowy podciąg ciągu Fibonacciego następująco:

>>> # Fibonacci series:
... # the sum of two elements defines the next
... a, b = 0, 1
>>> while a < 10:
...     print(a)
...     a, b = b, a+b
...
0
1
1
2
3
5
8

Ten przykład wprowadza kilka nowych funkcji.

  • Pierwsza linia zawiera wielokrotne przypisanie: zmienne a i b jednocześnie dostają nowe wartości 0 i 1. W ostatniej linii jest ponownie wykorzystane, demonstrując, że wyrażenia po prawej stronie są ewaluowane wcześniej, zanim którekolwiek z przypisań ma miejsce. Wyrażenia po prawej stronie są ewaluowane od lewej do prawej.

  • Pętla while wykonuje się dopóki warunek (tutaj: a < 10) pozostaje prawdziwy. W Pythonie, tak jak w C, każda niezerowa liczba całkowita jest prawdziwa; zero jest fałszywe. Warunek może być również ciągiem znaków lub listą, tak naprawdę jakąkolwiek sekwencją; cokolwiek o niezerowej długości jest prawdziwe, puste sekwencje są fałszywe. Warunek użyty w przykładzie jest prostym porównaniem. Standardowe operatory porównań pisane są tak samo jak w C: < (mniejsze niż), > (większe niż), == (równe), <= (mniejsze lub równe), >= (większe lub równe) i != (różne).

  • Ciało pętli jest wcięte: indentacja (wcięcia) jest sposobem na grupowanie instrukcji. W trybie interaktywnym trzeba wprowadzić znak(i) spacji lub tabulacji, aby wciąć wiersz. W praktyce będziesz przygotowywać bardziej skomplikowane dane wejściowe dla Pythona za pomocą edytora tekstu; wszystkie przyzwoite edytory tekstu mają funkcję automatycznych wcięć. W chwili, gdy wprowadza się jakąś instrukcję złożoną w czasie sesji interpretera Pythona, trzeba zakończyć ją pustym wierszem (bowiem interpreter nie wie, czy ostatni wprowadzony wiersz jest ostatnim z tej instrukcji). Ważne jest, aby każdy wiersz należący do tej samej grupy instrukcji, był wcięty o taką samą liczbę spacji lub znaków tabulacji.

  • Funkcja print() wypisuje wartość argumentu(-ów), które jej podano. Różnica pomiędzy tą instrukcją, a zwykłym zapisem wyrażenia, które chce się wypisać (tak jak robiliśmy to w przykładzie z kalkulatorem) występuje w sposobie obsługi wielu wyrażeń i napisów. Łańcuchy znaków wypisywane są bez cudzysłowów, a pomiędzy nimi zapisywane są spacje, tak aby można było ładnie sformatować pojawiający się napis, na przykład:

    >>> i = 256*256
    >>> print('The value of i is', i)
    The value of i is 65536
    

    Keyword argument end można wykorzystać, aby uniknąć znaku nowej linii po wypisaniu lub aby zakończyć wypisanie innym ciągiem znaków:

    >>> a, b = 0, 1
    >>> while a < 1000:
    ...     print(a, end=',')
    ...     a, b = b, a+b
    ...
    0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
    

Przypisy

1

Jako że ** ma wyższą precedencję niż -, -3**2 zostanie zinterpretowane jako -(3**2) i zwróci -9. Aby tego uniknąć i otrzymać 9, możesz użyć (-3)**2.

2

W przeciwieństwie do innych języków, znaki specjalne takie jak \n mają to samo znaczenie zarówno z pojedynczym ('…') jak i podwójnym ("…") cudzysłowem. Jedyną różnicą między nimi jest to, że wewnątrz pojedynczego cudzysłowu nie musisz escape’ować " (lecz musisz escape’ować \') i vice versa.