Hack Bulgaria
github.com/HackBulgaria
Днес ще си говорим за итератори и генератори!
animals = ['panda', 'dog', 'notcat', 'hatecats']
for animal in animals:
print('I like {}'.format(animal))
Има подредба! Може да индексираме!
a[start:end] # items start through end-1
a[start:] # items start through the rest of the array
a[:end] # items from the beginning through end-1
a[start:end:step] # start through not past end, by step
a[:] # a copy of the whole array
frameworks = ['django', 'angular', 'rails']
frameworks.append(frameworks)
frameworks[-1] is frameworks # True
print(frameworks) # ['django', 'angular', 'rails', [...]]
>>> python_frameworks = ["Django", "Flask"]
>>> frameworks = [python_frameworks, 'angular', 'rails']
>>> frameworks
[['Django', 'Flask'], 'angular', 'rails']
>>> python_frameworks.append("Pyramid")
>>> frameworks
[['Django', 'Flask', 'Pyramid'], 'angular', 'rails']
Като списък, но не може да се променя
python_frameworks = ("Django", "Flask")
python_frameworks[1] = Pyramid
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> web_framewokrs = (["Django", "Flask"], ["AngularJS", "Dojo"])
>>> web_framewokrs[0].append("Pyramid")
(['Django', 'Flask', 'Pyramid'], ['AngularJS', 'Dojo'])
Просто множества!
hackers = {"Rado", "Kamen", "Ivo"}
set3 = set1 & set2 # Intersection
set4 = set1 | set2 # Union
set5 = set1 - set3 # Set difference
set6 = set1 ^ set2 # Symmetric difference
issubset = set1 <= set2 # Subset test
issuperset = set1 >= set2 # Superset test
Нямаме подредба!
lotr_heroes = {
'Gandalf': 'the grey',
'Frodo': 'Baggins',
}
lotr_heroes['Saruman'] = 'the white'
Нямаме подредба!
dict се създава по още няколко начина
>>> dict([('Ivo', '22'), ('Rado', '24'), ('Fandalf', 400)])
{'Rado': '24', 'Fandalf': 400, 'Ivo': '22'}
[израз for променлива in поредица if условие]
[x for x in [1,2,3,4,5,6] if x % 2 == 0]
for panda in pandas:
print(panda.name)
__iter__ Връща итератор, с който можем да обходим нашата колекция
__next__ Връща следващата стойност в обхождането
iter(strucutre) вика __iter__
next(structure) вика __next__
>>> team = dict([('Ivo', '22'), ('Rado', '24'), ('Fandalf', 400)])
>>> iterator = iter(team)
>>> next(iterator)
'Rado'
>>> next(iterator)
'Fandalf'
>>> next(iterator)
'Ivo'
>>> next(iterator)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
iter се опитва да извика __iter__ метода на аргумента си, но ако се окаже, че такъв няма конструира итератор, като просто извиква __getitem__ с последователни естествени числа, започвайки от нула, докато не се хвърли StopIteration
class MyMoney:
def __getitem__(self, index):
if index > 20:
raise StopIteration()
return 30 ** index
>>> ivo_money = MyMoney()
>>> for money in ivo_money:
>>> print(money)
1
30
900
27000
810000
24300000
729000000
21870000000
656100000000
19683000000000
590490000000000
17714700000000000
531441000000000000
15943230000000000000
478296900000000000000
14348907000000000000000
430467210000000000000000
12914016300000000000000000
387420489000000000000000000
11622614670000000000000000000
348678440100000000000000000000
>>> numbers = [[1,2,3], [1,2,3], [1,2,3]]
>>> sums = map(lambda x: sum(x), numbers)
>>> numbers[2].append(22)
>>> next(sums)
6
>>> next(sums)
6
>>> next(sums)
28
Други мързеливи функции:
class FibUpTo:
def __init__(self, up_to):
self.up_to = up_to
self.num = 0
self.a = 1
self.b = 1
def __iter__(self):
return self
def __next__(self):
if self.num > self.up_to:
raise StopIteration
if self.num < 2:
self.num += 1
return 1
self.a, self.b = self.b, self.a + self.b
self.num += 1
return self.b
fib = FibUpTo(10)
for number in fib:
print(number)
Генератори
def panda_meals():
yield 'Bamboo One'
yield 'Bamboo Two'
yield 'Bamboo Three'
yield 'Bamboo Four'
yield 'Bamboo Five'
yield 'Bamboo Six'
meals = panda_meals()
for meal in meals:
print("Num num num " + meal)
И тях ги мързи!
def fib():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
Каква е разликата?
[x for x in [1,2,3,4,5,6] if x % 2 == 0]
(x for x in [1,2,3,4,5,6] if x % 2 == 0)
Кое от нещата, които ползваме е мързеливо?
with open ("text.txt", "r") as myfile:
for line in myfile:
print(line)
cursor.execute('''SELECT name, email, date_of_birth FROM users''')
for row in cursor:
get_horoscope(row[3])
send_email(email)
print('{0} : {1}, {2}'.format(row[0], row[1], row[2]))
By Hack Bulgaria