Какво ще изведе този код?
foods = ['spam', 'eggs', 'ham']
things = foods
things[1] = 'chips'
print(foods[1])
А този?
a = ['spam', 'eggs', 'ham']
b = a
c = a[:]
print(a is b, a is c)
print(a == b, a == c)
b[1] = 'milk'
print(a is b, a is c)
print(a == b, a == c)
my_string = '1234567890'
>>my_string[10]
IndexError: string index out of range
my_data = set(range(10))
for x in my_data:
print(x)
break
Ще изпринти един от елементите, без гаранция кой
{}
set()
1
None
True
[1, 2, 3]
(1, 2, 3)
12.0
'абвг'
lambda x: x**0
print, 5, 6, 7, 8
Кои от тези са валидни ключове за dict?
1, None, True, (1, 2, 3), 12.0, 'абвг', lambda-та и (print, 5, 6, 7 ,8)
my_dict = dict('12 34 16'.split() + [(False, False)])
print(len(my_dict), my_dict[0])
3 False
Според нас не сте
Има регистрирани грубо около 150 човека, предадени са ~70 решения
Имате време до началото на следващата ни среща, откровено не ви съветваме да чакате последния момент.
Забелязахме някои подробности в това, което е предадено до момента, на които е важно да обърнем внимание, за да имате време да ги поправите преди края на срока на домашното
if thingie == 'zero':
return 0
elif thingie == 'one':
return 1
elif thingie == 'THE ANSWER':
return 6*7
else:
return 'You are confusing me! STAHP!'
Само ако в python имаше някакъв вграден тип структура, която може да асоциира един обект с друг… Може би нещо, което да можем да индексираме с 'THE ANSWER' и то да ни върне 42… Би било супер яко!
number_names = {
0: 'zero',
1: 'one',
2: 'two',
…
42: 'THE ANSWER'
}
В древните програмистки книги се говори за митична структура от данни, която подрежда елементите си линейно в паметта и може да бъде индексирана с числата 0, 1, 2 и т.н., за да получаваме елемента на съответната позиция в нея. Някои смели душѝ дори твърдят, че има имплементация на такова нещо в python.
Казано е, че двете най-трудни неща в програмирането са
Ако една константна стойност се срещне повече от веднъж в кода ви, то тя задължително трябва да стане стойност на променлива или константа
# LO6O(mi e)!!!!
if argument == 41:
return 'WRONG'
elif argument == 42:
return 'CORRECT'
elif argument == 43:
return 'WRONG'
# SLED ASPERINA
wrong = 'WRONG'
correct = 'CORRECT'
if argument == 41:
return wrong
elif argument == 42:
return correct
elif argument == 43:
return wrong
Едно добро решение на това домашно спокойно може да се случи в рамките на 50-60 реда при просторно подреждане на нещата, така че да се четат лесно
Има добри решения и на по 20, но не искаме да се стремите към такива неща
НЕ ПРЕДАВАЙТЕ ФУНКЦИИ, КОИТО НЕ СЕ ПОЛЗВАТ! Така решенията ви стават по-тежки за четене и осмисляне, без това да допринася с нищо
Решението на тази задача се състои единствено от функции, които трябва да са „глобални“ във файла с решението. Можете да дефинирате всякакви спомагателни функции, променливи, класове и каквото си желаете(макар че други функции и класове по-скоро не са нужни), но функциите описани в условието трябва да са видими в глобалната област на файла с решението.
class solution:
def interpret_western_sign(day, month):
…
def interpret_chinese_sign(year):
…
def interpret_western_sign(day, month):
…
def interpret_chinese_sign(year):
…
PEP8! Това е конвенцията за стил на Python. Задължително спазване!
PEP8! Това е конвенцията за стил на Python. Задължително спазване!
Още много от източника
Никой не е запомнил целия pep8 само с четене
Всеки редактор може да бъде конфигуриран, така че да използва pep8, за да проверява кода ви и да се кара, когато не правите нещо правилно
Научете се как да ползвате добре редактора, който сте си избрали, това е много важно
pip install pep8
По същество за колекции
Когато имаме данни, най-логично е да ги слагаме в колекции.
nice_things = ['coffee', 'cheese', 'crackers', 'tea']
for thing in nice_things:
print('I tend to like {}'.format(thing))
можем и просто да ги индексираме
print(nice_things[1]) # cheese
print(nice_things[-1]) # tea
print(nice_things[-3]) # cheese
cute_animals = ['cat', 'raccoon', 'panda', 'red panda', 'marmot']
cute_animals[1:3] # ['raccoon', 'panda']
cute_animals[-1] # 'marmot'
cute_animals[1:-1] # ['raccoon', 'panda', 'red panda']
cute_animals[::-1] # ['marmot', 'red panda', 'panda', 'raccoon', 'cat']
cute_animals[-1:0:-1] # ['marmot', 'red panda', 'panda', 'raccoon']
cute_animals[-1:0:-2] # ['marmot', 'panda']
Списъците съдържат "указатели" към елементи
coffee, cheese, crackers, tea = 'coffee', 'cheese', 'crackers', 'tea' # unpacking
things_i_like = [coffee, cheese, crackers]
things_you_like = [crackers, coffee, tea]
things_i_like[0] == things_you_like[1] # True
things_i_like[0] is things_you_like[1] # True
Това позволява някои интересни неща
cheeses = ['brie', 'bergkäse', 'kashkaval', 'leipäjuusto']
cheeses.append(cheeses)
cheeses[-1] is cheeses # True
print(cheeses) # ['brie', 'bergkäse', 'kashkaval', 'leipäjuusto', [...]]
cheeses = ['brie', 'bergkäse', 'kashkaval', 'leipäjuusto']
teas = ['chai', 'earl grey', 'jasmine', 'oolong']
breakfast = [cheeses, teas]
print(breakfast[0][1]) # bergkäse
breakfast[1][2] = ['шкембе', 'люби чушки', 'оцет с чесън']
print(teas) # ?
['chai', 'earl grey', ['шкембе', 'люби чушки', 'оцет с чесън'], 'oolong']
.index(element)
- Индексът на първото срещане на element в списъка или гърми с ValueError
.count(element)
- Броят срещания на element в списъка
.append(element)
- Добавя element в края на списъка
.extend(elements)
- Добавя елементите на elements в списъка (като + ама по-бързо)
.sort()
- Сещате се
range връща итерируемо за интервал от числа
numbers = range(3)
for number in numbers:
print('We can count to {}'.format(number))
range интервалът може да не започва от нула
numbers = range(10, 13)
for number in numbers:
print('We can count to {}'.format(number))
последователност, n-торка(n-орка), тюпъл
като списък, но с постоянен състав
people = ('Niki', 'Kiro', 'Genata')
people[2] # Genata
people[1] # Kiro
people[0] # Niki
people[1] = 'бобър'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
последователността от елементи в кортежа не може да се променя, самите елементи може да изменят вътрешната си структура
change_me = ([1, 2, 3], [4, 5, 6], [7, 8, 9])
change_me[1][1] = 0
change_me[2][0] = 'c'
print(change_me) # ([1, 2, 3], [4, 0, 6], ['c', 8, 9])
алтернативен синтаксис за кортежи
people = 'Niki', 'Kiro', 'Genata'
people = 'Niki',
people = ('Niki') # най-вероятно не е каквото очаквате
Има методите `index` и `count` като на списъците
Ако имате n-торка, съдържаща само имена от лявата страна на присвояване, може да постигнете интересни ефекти:
(a, b) = 1, 2
print(a) # 1
Всъщност скобите изобщо не са задължителни
a, b = 1, 2
print(a) # 1
Или
numbers = (1, 2, 3)
a, b, c = numbers
Можем да правим и така:
a, *b, c = 1, 2, 3, 4, 5
a = 1
b = [2, 3, 4]
c = 5
Сравняват се лексикографски:
>>> (1, 2) < (1, 3)
True
>>> (1, 2) < (1, 2)
False
>>> (1, 2) < (1, 2, 3)
True
>>> [1, 2] < [1, 3]
True
>>> (1, 2) < [1, 3] # tuple vs. list
# поражда грешка:
# TypeError: unorderable types: tuple() < list()
Опашка (queue, FIFO buffer) - можете да ползвате списък.
adjectives = []
def add_adjective(items):
adjectives.append(items)
def get_adjective():
return adjectives.pop(0)
add_adjective('Magic')
add_adjective('Woody Allen')
add_adjective('Zombie')
add_adjective('Superhero')
print(' '.join(adjectives) + ' Jesus!') # Magic Woody Allen Zombie Superhero Jesus!
Stack?
Множества(за всякакви практически цели, неразличими от математическата абстракция със същото име)
favourite_numbers = set()
favourite_numbers.add(13)
favourite_numbers.add(73)
favourite_numbers.add(32)
favourite_numbers.add(73)
favourite_numbers.add(1024)
favourite_numbers.add(73)
print(favourite_numbers) # {32, 73, 666, 13, 1024}
Множествата са итерируеми и НЕподредени
for num in favourite_numbers:
print('I really like the number ' + str(num))
можем да проверяваме за принадлежност
73 in favourite_numbers # True
Има синтаксис за създаване на множества(както може би сте се досетили)
favourite_numbers = {32, 73, 666, 13, 1024}
{} не е празния set!
>>> {1, 2, 3} | {2, 3, 4}
{1, 2, 3, 4}
>>> {1, 2, 3} & {2, 3, 4}
{2, 3}
>>> {1, 2, 3} - {2, 3, 4}
{1}
>>> {1, 2, 3} ^ {2, 3, 4}
{1, 4}
>>> {1, 2, 3} < {2, 3, 4}
False
>>> {2, 3} < {2, 3, 4} # < - подмножество
True
>>> {2, 3} == {2.0, 3}
True
>>> {1, 2}.isdisjoint({3, 4})
True
Индексите не винаги са достатъчно информативни
artist_names = {
'Eddie': 'Vedder',
'Maynard': 'Keenan',
'Matthew': 'Bellamy',
'James': 'LaBrie',
}
print('Eddie\'s last names is ' + artist_names['Eddie'])
{} е празен речник, по простата причина, речниците са доста по-често използвана структура от множествата
можем да добавяме нови стойности във вече създаден речник
names['Devin'] = 'Townsend'
print(names) # {'Devin': 'Townsend', 'Matthew': 'Bellamy', 'Eddie': 'Vedder', 'James': 'LaBrie', 'Maynard': 'Keenan'}
речникът също е неподреден
Чрез наименовани параметри към конструктора (не питайте):
>>> dict(france="Paris", italy="Rome")
{'italy': 'Rome', 'france': 'Paris'}
Чрез списък от двойки
>>> dict([('One', 'I'), ('Two', 'II')])
{'Two': 'II', 'One': 'I'}
Чрез списък от ключове и стойност по подразбиране
>>> dict.fromkeys([1, 2, 3], 'Unknown')
{1: 'Unknown', 2: 'Unknown', 3: 'Unknown'}
data = [('John', 'Tilsit'), ('Eric', 'Cheshire'), ('Michael', 'Camembert'),
('Terry', 'Gouda'), ('Terry', 'Port Salut'), ('Michael', 'Edam'),
('Eric', 'Ilchester'), ('John', 'Fynbo')]
def cheeses_by_owner(cheeses_data):
by_owner = {}
for owner, cheese in cheeses_data: # <- tuple unpacking
if owner in by_owner:
by_owner[owner].append(cheese)
else:
by_owner[owner] = [cheese]
return by_owner
за любознателните: map и filter са мързеливи
[израз for променлива in поредица if условие]
>>> [x * x for x in range(0, 10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> [x * x for x in range(0, 10) if x % 2]
[1, 9, 25, 49, 81]
Един list comprehension може да се вложи в друг, защото връща нещо итерируемо
>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
>>> import math
>>> {int(math.sqrt(x)) for x in range(1,100)}
{1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> {i : chr(65+i) for i in range(10)}
{0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E', 5: 'F', 6: 'G', 7: 'H', 8: 'I', 9: 'J'}
from collections import deque
adjectives = deque()
def add_adjective(items):
adjectives.append(items)
def get_adjective():
return adjectives.popleft()
add_adjective('Komodo Dragon')
add_adjective('Telepathic')
add_adjective('Vampire')
add_adjective('Quantum Hovercraft')
print(' '.join(adjectives) + ' Jesus') # Komodo Dragon Telepathic Vampire Quantum Hovercraft Jesus
from collections import defaultdict
data = [('John', 'Tilsit'), ('Eric', 'Cheshire'), ('Michael', 'Camembert'),
('Terry', 'Gouda'), ('Terry', 'Port Salut'), ('Michael', 'Edam'),
('Eric', 'Ilchester'), ('John', 'Fynbo')]
def cheeses_by_owner(cheeses_data):
by_owner = defaultdict(list)
for owner, cheese in cheeses_data:
by_owner[owner].append(cheese)
return by_owner
>>> import itertools
>>> help(itertools)
cute_animals
, а не cute_animal_list
?