﻿>>> for x in [1, 2, 3, 4]: (print x ** 2, end=' ')
...
1 4 9 16
>>> for x in (1, 2, 3, 4): (print x ** 3, end=' ')
...
1 8 27 64
>>> for x in 'mielonka': (print x * 2, end=' ')
...
mm ii ee ll oo nn kk aa


>>> f = open('script1.py')     # Odczytanie 4-wierszowego skryptu z bieżącego katalogu
>>> f.readline()               # funkcja readline wczytuje po jednym wierszu
'import sys\n'
>>> f.readline()
'print sys.path\n'
>>> f.readline()
'x = 2\n'
>>> f.readline()
'print 2 ** 33\n'
>>> f.readline()               # Zwraca pusty ciąg znaków na końcu pliku
''


>>> f = open('script1.py')     # __next__ również wczytuje po jednym wierszu
>>> f.__next__()               # ale wywołuje wyjątek na końcu pliku
'import sys\n'
>>> f.__next__()
'print sys.path\n'
>>> f.__next__()
'x = 2\n'
>>> f.__next__()
'print 2 ** 33\n'
>>> f.__next__()
Traceback (most recent call last):
...pominięta treść wyjątku...
StopIteration


>>> for line in open('script1.py'):         # Użycie iteratorów plików
...    print(line.upper(), end='')          # Wywołuje __next__, przechwytuje StopIteration
...
IMPORT SYS
PRINT(SYS.PATH)
X = 2
PRINT(2 ** 33)


>>> for line in open('script1.py').readlines():
...    print(line.upper(), end='')
...
IMPORT SYS
PRINT(SYS.PATH)
X = 2
PRINT(2 ** 33)


>>> f = open('script1.py')
>>> while True:
...    line = f.readline()
...    if not line: break
...    print line.upper(),
...
...te same dane wyjściowe...


>>> f = open('script1.py')
>>> f.__next__()                 # Bezpośrednie wywołanie metody iteratora
'import sys\n'
>>> f.__next__()
'print(sys.path)\n'

>>> f = open('script1.py')
>>> next(f)                      # Niejawne wywołanie metody __next__
'import sys\n'
>>> next(f)
'print(sys.path)\n'


>>> L = [1, 2, 3]
>>> I = iter(L)                  # Pozyskanie obiektu iteratora
>>> I.next()                     # Odczyt następnego elementu iteratora
1
>>> I.next()
2
>>> I.next()
3
>>> I.next()
Traceback (most recent call last):
...pominięta część wyniku...
StopIteration


>>> f = open('script1.py')
>>> iter(f) is f
True
>>> f.__next__()
'import sys\n'


>>> L = [1, 2, 3]
>>> iter(L) is L
False
>>> L.__next__()
AttributeError: 'list' object has no attribute '__next__'

>>> I = iter(L)
>>> I.__next__()
1
>>> next(I)                          # Równoważne I.__next__()
2


>>> L = [1, 2, 3]
>>>
>>> for X in L:                      # Iteracja automatyczna
...     print(X ** 2, end=' ')       # Wywołuje funkcję iter(), metodę __next__(), przechwytuje wyjątki
...
1 4 9

>>> I = iter(L)                      # Ręczna iteracja: pętla for robi to samo niejawnie
>>> while True:
... try:                             # Instrukcja try pozwala obsługiwać wyjątki
...      X = next(I)                 # Alternatywnie: I.__next__()
... except StopIteration:
...      break
... print(X ** 2, end=' ')
...
1 4 9


>>> D = {'a':1, 'b':2, 'c':3}
>>> for key in D.keys():
...    print(key, D[key])
...
a 1
c 3
b 2


>>> I = iter(D)
>>> next(I)
'a'
>>> next(I)
'c'
>>> next(I)
'b'
>>> next(I)
Traceback (most recent call last):
...pominięta część wyniku...
StopIteration


>>> for key in D:
...     print(key, D[key])
...
a 1
c 3
b 2


>>> import os
>>> P = os.popen('dir')
>>> P.__next__()
' Volume in drive C is SQ004828V03\n'
>>> P.__next__()
' Volume Serial Number is 08BE-3CD4\n'
>>> next(P)
TypeError: _wrap_close object is not an iterator


>>> R = range(5)
>>> R                         # W 3.0 zakresy są obiektami iterowanymi
range(0, 5)
>>> I = iter(R)               # Użycie protokołu iteracyjnego
>>> next(I)
0
>>> next(I)
1
>>> list(range(5))            # Użycie listy do jednoczesnej prezentacji wszystkich wyników
[0, 1, 2, 3, 4]


>>> E = enumerate('spam')     # Wynik funkcji enumerate() również jest obiektem iterowanym
>>> E
<enumerate object at 0x0253F508>
>>> I = iter(E)
>>> next(I)                   # Wygenerowanie wyników z użyciem protokołu iteracyjnego
(0, 's')
>>> next(I)                   # Przekształcenie na listę generuje wszystkie elementy jednocześnie
(1, 'p')
>>> list(enumerate('spam'))
[(0, 's'), (1, 'p'), (2, 'a'), (3, 'm')]


>>> L = [1, 2, 3, 4, 5]
>>> for i in range(len(L)):
...    L[i] += 10
...
>>> L
[11, 12, 13, 14, 15]


>>> L = [x + 10 for x in L]
>>> L
[21, 22, 23, 24, 25]


>>> L = [x + 10 for x in L]


>>> res = []
>>> for x in L:
...    res.append(x + 10)
...
>>> res
[21, 22, 23, 24, 25]


>>> f = open('script1.py')
>>> lines = f.readlines()
>>> lines
['import sys\n', 'print sys.path\n', 'x = 2\n', 'print 2 ** 33\n']


>>> lines = [line.rstrip() for line in lines]
>>> lines
['import sys', 'print sys.path', 'x = 2', 'print 2 ** 33']


>>> lines = [line.rstrip() for line in open('script1.py')]
>>> lines
['import sys', 'print sys.path', 'x = 2', 'print 2 ** 33']


>>> [line.upper() for line in open('script1.py')]
['IMPORT SYS\n', 'PRINT(SYS.PATH)\n', 'X = 2\n', 'PRINT(2 ** 33)\n']
>>> [line.rstrip().upper() for line in open('script1.py')]
['IMPORT SYS', 'PRINT(SYS.PATH)', 'X = 2', 'PRINT(2 ** 33)']
>>> [line.split() for line in open('script1.py')]
[['import', 'sys'], ['print(sys.path)'], ['x', '=', '2'], ['print(2', '**','33)']]
>>> [line.replace(' ', '!') for line in open('script1.py')]
['import!sys\n', 'print(sys.path)\n', 'x!=!2\n', 'print(2!**!33)\n']
>>> [('sys' in line, line[0]) for line in open('script1.py')]
[(True, 'i'), (True, 'p'), (False, 'x'), (False, 'p')]


>>> lines = [line.rstrip() for line in open('script1.py') if line[0] == 'p']
>>> lines
['print sys.path', 'print 2 ** 33']


>>> res = []
>>> for line in open('script1.py'):
...     if line[0] == 'p':
...         res.append(line.rstrip())
...
>>> res
['print sys.path', 'print 2 ** 33']


>>> [x + y for x in 'abc' for y in 'lmn']
['al', 'am', 'an', 'bl', 'bm', 'bn', 'cl', 'cm', 'cn']


>>> res = []
>>> for x in 'abc':
...    for y in 'lmn':
...       res.append(x + y)
...
>>> res
['al', 'am', 'an', 'bl', 'bm', 'bn', 'cl', 'cm', 'cn']


>>> for line in open('script1.py'):              # Użycie iteratorów plików
...     print(line.upper(), end='')
...
IMPORT SYS
PRINT SYS.PATH
X = 2
PRINT(2 ** 33)


>>> uppers = [line.upper() for line in open('script1.py')]
>>> uppers
['IMPORT SYS\n', 'PRINT SYS.PATH\n', 'X = 2\n', 'PRINT 2 ** 33\n']
>>> map(str.upper, open('script1.py'))           # map() jest w 3.0 obiektem iterowanym
<map object at 0x02660710>

>>> list(map(str.upper, open('script1.py')))
['IMPORT SYS\n', 'PRINT SYS.PATH\n', 'X = 2\n', 'PRINT 2 ** 33\n']

>>> 'y = 2\n' in open('script1.py')
False
>>> 'x = 2\n' in open('script1.py')
True


>>> sorted(open('script1.py'))
['import sys\n', 'print(2 ** 33)\n', 'print(sys.path)\n', 'x = 2\n']
>>> list(zip(open('script1.py'), open('script1.py')))
[('import sys\n', 'import sys\n'), ('print(sys.path)\n', 'print(sys.path)\n'),
('x = 2\n', 'x = 2\n'), ('print(2 ** 33)\n', 'print(2 ** 33)\n')]
>>> list(enumerate(open('script1.py')))
[(0, 'import sys\n'), (1, 'print(sys.path)\n'), (2, 'x = 2\n'),
(3, 'print(2 ** 33)\n')]
>>> list(filter(bool, open('script1.py')))
['import sys\n', 'print(sys.path)\n', 'x = 2\n', 'print(2 ** 33)\n']
>>> import functools, operator
>>> functools.reduce(operator.add, open('script1.py'))
'import sys\nprint(sys.path)\nx = 2\nprint(2 ** 33)\n'


>>> sum([3, 2, 4, 1, 5, 0])                 # sum oczekuje samych liczb
15
>>> any(['spam', '', 'ni'])
True
>>> all(['spam', '', 'ni'])
False
>>> max([3, 2, 5, 1, 4])
5
>>> min([3, 2, 5, 1, 4])
1


>>> max(open('script1.py'))                 # Wiersz z ciągiem znaków o najwyższej wartości
'x = 2\n'
>>> min(open('script1.py'))
'import sys\n'


>>> list(open('script1.py'))
['import sys\n', 'print sys.path\n', 'x = 2\n', 'print 2 ** 33\n']

>>> tuple(open('script1.py'))
('import sys\n', 'print sys.path\n', 'x = 2\n', 'print 2 ** 33\n')

>>> '&&'.join(open('script1.py'))
'import sys\n&&print sys.path\n&&x = 2\n&&print 2 ** 33\n'

>>> a, b, c, d = open('script1.py')
>>> a, d
('import sys\n', 'print 2 ** 33\n')
>>> a, *b = open('script1.py')                   # Rozszerzona składnia Pythona 3.0
>>> a, b
('import sys\n', ['print(sys.path)\n', 'x = 2\n', 'print(2 ** 33)\n'])


>>> set(open('script1.py'))
{'print(sys.path)\n', 'x = 2\n', 'print(2 ** 33)\n', 'import sys\n'}
>>> {line for line in open('script1.py')}
{'print(sys.path)\n', 'x = 2\n', 'print(2 ** 33)\n', 'import sys\n'}
>>> {ix: line for ix, line in enumerate(open('script1.py'))}
{0: 'import sys\n', 1: 'print(sys.path)\n', 2: 'x = 2\n', 3: 'print(2 ** 33)\n'}


>>> {line for line in open('script1.py') if line[0] == 'p'}
{'print(sys.path)\n', 'print(2 ** 33)\n'}
>>> {ix: line for (ix, line) in enumerate(open('script1.py')) if line[0] == 'p'}
{1: 'print(sys.path)\n', 3: 'print(2 ** 33)\n'}


>>> def f(a, b, c, d): print(a, b, c, d, sep='&')
...
>>> f(1, 2, 3, 4)
1&2&3&4
>>> f(*[1, 2, 3, 4])                        # Rozpakowanie listy argumentów
1&2&3&4

>>> f(*open('script1.py'))                  # Iteracja po wierszach
import sys
&print(sys.path)
&x = 2
&print(2 ** 33)


>>> X = (1, 2)
>>> Y = (3, 4)
>>>
>>> list(zip(X, Y))                         # zip() krotek: zwraca obiekt iterowany
[(1, 3), (2, 4)]
>>>
>>> A, B = zip(*zip(X, Y))                  # Rozpakowanie zipa!
>>> A
(1, 2)
>>> B
(3, 4)


>>> zip('abc', 'xyz')                       # Obiekt iterowany w 3.0, lista w 2.6
<zip object at 0x02E66710>
>>> list(zip('abc', 'xyz'))                 # Wymuszenie listy wyników w 3.0
[('a', 'x'), ('b', 'y'), ('c', 'z')]


C:\\misc> c:\python30\python
>>> R = range(10)                           # range() zwraca iterator, nie listę
>>> R
range(0, 10)

>>> I = iter(R)                             # Przekształcenie zakresu na iterator
>>> next(I)                                 # Przejście do następnej wartości
0                                           # Pętle for, rozwinięcia itp. wykonują to w sposób niejawny
>>> next(I)
1
>>> next(I)
2
>>> list(range(10))                         # Przekształcenie na listę
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


>>> len(R)                           # range obsługuje len() i odczyt po indeksie
10
>>> R[0]
0
>>> R[-1]
9

>>> next(I)                          # Kontynuacja iteratora od ostatniego miejsca
3
>>> I.__next__()                     # .next() działa tak samo jak __next__(), ale zaleca się stosować next()
4


>>> M = map(abs, (-1, 0, 1))             # map() zwraca iterator, nie listę
>>> M
<map object at 0x0276B890>
>>> next(M)                              # Ręczne użycie iteratora, „zużywa” wyniki
1                                        # Iterator nie obsługuje funkcji len() ani indeksowania
>>> next(M)
0
>>> next(M)
1
>>> next(M)
StopIteration
>>> for x in M: print(x)                 # Iterator zwrócony z map() nie zawiera już żadnych elementów
...
>>> M = map(abs, (-1, 0, 1))             # Ponowne przetwarzanie wymaga stworzenia nowego iteratora
>>> for x in M: print(x)                 # Konteksty iteracyjne automatycznie używają funkcji next()
...
1
0
1
>>> list(map(abs, (-1, 0, 1)))           # Iterator można przekształcić na listę
[1, 0, 1]


>>> Z = zip((1, 2, 3), (10, 20, 30))     # zip() działa tak samo: zwraca jednorazowy iterator
>>> Z
<zip object at 0x02770EE0>

>>> list(Z)
[(1, 10), (2, 20), (3, 30)]

>>> for pair in Z: print(pair)           # Po pełnym przebiegu elementy są wyczerpane…
...

>>> Z = zip((1, 2, 3), (10, 20, 30))
>>> for pair in Z: print(pair)           # Iterator może być użyty ręcznie lub automatycznie
...
(1, 10)
(2, 20)
(3, 30)

>>> Z = zip((1, 2, 3), (10, 20, 30))
>>> next(Z)
(1, 10)
>>> next(Z)
(2, 20)


>>> filter(bool, ['spam', '', 'ni'])
<filter object at 0x0269C6D0>
>>> list(filter(bool, ['spam', '', 'ni']))
['spam', 'ni']


>>> R = range(3)                         # range() pozwala na wielokrotną iterację
>>> next(R)
TypeError: range object is not an iterator

>>> I1 = iter(R)                            # Dwa iteratory jednego obiektu
>>> next(I1)
0
>>> next(I1)                                # I1 znajduje się na innej pozycji niż I2
1
>>> I2 = iter(R)
>>> next(I2)
0
>>> next(I1)
2


>>> Z = zip((1, 2, 3), (10, 11, 12))
>>> I1 = iter(Z)
>>> I2 = iter(Z)                            # Dwa iteratory jednego wyniku funkcji zip()
>>> next(I1)
(1, 10)
>>> next(I1)
(2, 11)
>>> next(I2)                                # I2 znajduje się na tej samej pozycji co I1!
(3, 12)

>>> M = map(abs, (-1, 0, 1))                # Tak samo działa wynik map() oraz filter()
>>> I1 = iter(M); I2 = iter(M)
>>> print(next(I1), next(I1), next(I1))
1 0 1
>>> next(I2)
StopIteration

>>> R = range(3)                            # Natomiast wynik range() pozwala na wielokrotną iterację
>>> I1, I2 = iter(R), iter(R)
>>> [next(I1), next(I1), next(I1)]
[0 1 2]
>>> next(I2)
0


>>> D = dict(a=1, b=2, c=3)
>>> D
{'a': 1, 'c': 3, 'b': 2}

>>> K = D.keys()                            # W 3.0 obiekt widoku, nie lista
>>> K
<dict_keys object at 0x026D83C0>

>>> next(K)                                 # Widoki nie są iteratorami
TypeError: dict_keys object is not an iterator

>>> I = iter(K)                             # Widoki dostarczają iteratory,
>>> next(I)                                 # które można obsługiwać ręcznie,
'a'                                         # ale nie obsługują len() i indeksowania
>>> next(I)
'c'

>>> for k in D.keys(): print(k, end=' ')    # W kontekstach iteracyjnych odbywa się to automatycznie
...
a c b


>>> K = D.keys()
>>> list(K)                                 # Przekształcenie na listę
['a', 'c', 'b']

>>> V = D.values()                          # Podobnie dla wyniku metod values() i items()
>>> V
<dict_values object at 0x026D8260>
>>> list(V)
[1, 3, 2]

>>> list(D.items())
[('a', 1), ('c', 3), ('b', 2)]

>>> for (k, v) in D.items(): print(k, v, end=' ')
...
a 1 c 3 b 2


>>> D                                       # Słowniki oferują własny iterator
{'a': 1, 'c': 3, 'b': 2}                    # w każdej iteracji zwracający kolejny klucz
>>> I = iter(D)
>>> next(I)
'a'
>>> next(I)
'c'

>>> for key in D: print(key, end=' ')       # Metoda keys() nie jest niezbędna do iteracji po kluczu,
...                                         # ale w 3.0 keys() również zwraca obiekt iterowany!
a c b


>>> D
{'a': 1, 'c': 3, 'b': 2}
>>> for k in sorted(D.keys())): print(k, D[k], end=' ')
...
a 1 b 2 c 3

>>> D
{'a': 1, 'c': 3, 'b': 2}
>>> for k in sorted(D): print(k, D[k], end=' ')   # Zalecana technika sortowania kluczy
...
a 1 b 2 c 3
