Junior Python School
705 subscribers
92 photos
29 links
Surprising the python community with pure python 🔝

Moving channel from Russian to English.


Enthusiastic reviews can be written to @pythonjuniorschoolacc ❤️
Download Telegram
Что выведет запрос?

Вариант 1 - 2
👍👍👍 11%
Вариант 2 - 6
👍👍👍👍👍👍👍👍 32%
Вариант 3 - 4
👍👍👍👍👍👍 21%
Вариант 4 - 1
👍👍 5%
А где python? - 6
👍👍👍👍👍👍👍👍 32%
👥 19 человек уже проголосовало.
Channel name was changed to «Junior Python School»
Если у вас есть знакомые питонисты - киньте им этот тест, запутаться в этом может каждый.



fromkeys - позволяет из последовательности и значения сделать словарь с элементами последовательности с данным значением
>>> dict.fromkeys(['python', 'sql', 'c++'], 'good')

{'python': 'good', 'sql': 'good', 'c++': 'good'}



Или setdefault - если ключ в словаре не найден - то создаст этот ключ с заданным значением по умолчанию и вернет его.
>>> d = {'python': 'cool', 'js': 'oh no', 'sql': 'good'}

>>> d.setdefault('js', 'bad')

'oh no'

>>> d.setdefault('php', 'bad')

'bad'



Или get - позволяет получить значение из словаря по ключу или какое-то значение по умолчанию, если ключ не найден.
Пользуюсь этим методом постоянно.
Часто удобнее, чем просто стучаться к элементу через квадратные скобочки ибо не выкидывает исключение KeyError, если ключа не найдено.
>>> d = {'python': 'cool', 'js': 'oh no', 'sql': 'good'}

>>> d.get('js', 'no such key')

'oh no'

>>> d.get('php', 'no such key')

'no such key'

>>> d['php']

Traceback (most recent call last):
 File "<input>", line 1, in <module>
KeyError: 'php'



Интересное происходит с popitem - этот метод возвращает случайную пару ключ-значение из словаря и удаляет его их словаря.
>>> d = {'python': 'cool', 'js': 'oh no', 'sql': 'good'}

>>> d.popitem()

('sql', 'good')

>>> d

{'python': 'cool', 'js': 'oh no'}



С pop похожая ситуация - этот метод удаляет заданное значение из словаря и возвращает значение удаленного элемента. При этом у метода есть тоже параметр по умолчанию, он возвращается если ключа не найдено. Если пара не найдена - кидается наше любимое исключение KeyError
>>> d = {'python': 'cool', 'js': 'oh no', 'sql': 'good'}

>>> d.pop('php', 'no such value')

'no such value'

>>> d.pop('js')

'oh no'

>>> d.pop('php')

Traceback (most recent call last):
 File "<input>", line 1, in <module>
KeyError: 'php'



Про keys, values и items - особо говорить не нужно. Нужны чаще всего для итерации по словарю. Нужно только обратить внимание, что возвращаются объекты типов dict_keys, dict_values и dict_items
>>> d = {'python': 'cool', 'sql': 'good'}

>>> d.keys()

dict_keys(['python', 'sql'])

>>> d.values()

dict_values(['cool', 'good'])

>>> d.items()

dict_items([('python', 'cool'), ('sql', 'good')])



Посмотрим на вообще все публичные методы
(которые не начинаются с нижнего подчеркивания)
>>> [attr for attr in dir(dict()) if attr[0]!='_']

>>> ['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']



Мы не рассмотрели еще методы copy, clear и update.
C ними все не сложно:
copy - создает shallow копию данного словаря,
clean - удаляет все ключи и значения из словаря и оставляет его пустым,
update - обновляет словарь значениями из другого словаря.
>>> d1 = {1:1 , 2:3}
>>> d2 = {3:3 , 2:2}
>>> d1.update(d2)
>>> d1
{1: 1, 2: 2, 3: 3}



Лайфхак для пользователей python 3.5+
update можно заменить вот так:
{**d1, **d2}
{1: 1, 2: 2, 3: 3}
Пришло время обсудить вот этот тест.

Все несложно
Во-первых, потому что можно легко проверить ответ в интерпретаторе)
Во-вторых, потому что с тонкостью этой задачи сталкиваться приходится довольно часто.


Запустим в интерпретаторе:
>>> isinstance((), tuple)
True
>>> isinstance((1), tuple)
False
>>> isinstance((1, 2), tuple)
True

Все, можно спокойно выбрать правильный ответ))😜

Но почему так?
Что мы на самом деле делаем:
Мы проверяем является ли какое-то значение объектом класса кортеж.

Значение () - это способ объявления пустого кортежа

Значение (1) - это просто 1 в скобочках
>>> type((1))
<class 'int'>
Для того, чтобы сделать это значение кортежем нужно просто добавить запятую: (1,)
>>> type((1,))
<class 'tuple'>

Ну а (1, 2) - это простой кортеж из двух элементов.

Лайфхак:
Функция tuple() - позволяет сделать из любой последовательности кортеж.

Пример:
>>> tuple('join us')
('j', 'o', 'i', 'n', ' ', 'u', 's')
>>> tuple(['Поделись', 'каналом', 'c', 'друзьями'])
('Поделись', 'каналом', 'c', 'друзьями')
Наша команда создала тест

Просто 9 вопросов по python. В конце можно получить сертификат о прохождении - мелочь, а приятно)
Немного поменяли способ подсчета баллов теста выше.
Все результаты пересчитаны, чтобы стало проще
Интересно увидеть статистику по всем пользователям?
Anonymous Poll
50%
Покажите графики
19%
Покажите лучших
31%
Ещё тестов создайте
Статистика по тесту 📊.

Пока что его прошло 77 человек. Особенно радует, что многие проходили его несколько раз с одного ip, чтобы получить заветную пятерку!


Наша команда уже готовит следующий тест - не пропусти.


У нас есть план запустить бесплатный интенсив, без какой-либо жуткой рекламы, по модулю itertools.

Покажем базовые возможности, а также красивые и удобные фишки библиотеки.

Если интересно поучаствовать - напиши об этом нашему боту, хотим знать сколько тут замотивированных на учебу!




Поделись каналом с друзьями - мы сейчас только начинаем развиваться, и без твоей помощи ничего грандиозного не получится)

Твоя обратная связь мотивирует команду Junior Python School работать лучше и быстрее, пользуйся этим)

Участвуй в нашем конкурсе. Шансы выиграть что-то сейчас очень высоки!
Рождество? Ну чуточку новых знаний-то можно, в честь праздника?

Это был очень популярный вопрос на собеседованиях пару лет назад.

Но и сейчас вспоминают это иногда)

Что выведет программа?

Потом обязательно этот вопрос разберем, это очень важная тема.
А вот и сами варианты ответов)

Чур, не подглядывать в интерпретатор!!😜

1)
['I LOVE PYTHON']
['I HATE JS', 'I LOVE PYTHON']
['I LOVE PYTHON']

2)
['I LOVE PYTHON']
['I LOVE PYTHON', 'I HATE JS', 'I LOVE PYTHON']
['I LOVE PYTHON', 'I HATE JS', 'I LOVE PYTHON', 'I LOVE PYTHON']

3)
['I LOVE PYTHON']
['I HATE JS', 'I LOVE PYTHON']
['I LOVE PYTHON', 'I LOVE PYTHON']


4)
Нельзя использовать в качестве параметра функции изменяемый объект.
Даже pycharm сразу такие ошибки подсвечивает!

1 - 19
👍👍👍👍👍👍👍👍 58%
2 - 3
👍👍 9%
3 - 10
👍👍👍👍👍 30%
4 - 1
👍 3%
👥 33 человека уже проголосовало.
crazy_dict = {1: 'int',
1.0: 'float',
True: 'boolean'}
print(crazy_dict)

Наш стандартный вопрос:
Что выведет программа?

В интерпретатор смотреть не надо, мы его уже за вас проверили - правильный ответ в списке есть. Вроде.

1)
{1: 'int', 1.0: 'float', True: 'boolean'}
2)
{True: 'int'}
3)
{1.0: 'int', True:'boolean'}
4)
{1: 'boolean'}
5)
{1: 'float', True:'boolean'}

1 - 15
👍👍👍👍👍👍👍👍 50%
2 - 3
👍👍 10%
3 - 2
👍👍 7%
4 - 7
👍👍👍👍 23%
5 - 3
👍👍 10%
👥 30 человек уже проголосовало.
Давайте обсудим нашу рождественскую задачку

Вот теперь уже можно подсмотреть в интерпретатор)

Что за магия?

Просто нужно запомнить, что в момент инициализации функции автоматически инициализируются значения по-умолчанию у всех параметров и записываются в кортеж __defaults__

В кортеже __defaults__ не должно появляться изменяемых объектов, только неизменяемые.


Просто каждый раз, когда вы вызываете функцию с параметром по-умолчанию (явно не указывая этот параметр), python не инициализирует параметр заново, а ищет его в __defaults__.
И если параметр изменяемый, и вы до этого его меняли, то получится ситуация как в задачке.


Поэтому вывод - старайтесь не делать изменяемые объекты значениями по-умолчанию!


Как нужно правильно написать эту функцию?
def func(a=None):
if a is None:
a = []
a.append('I LOVE PYTHON')
print(a)


func()
func(['I HATE JS'])
func()

Домашнее задание!!
Попробуйте разобраться в интерпретаторе и обратите внимание на все существующие поля и методы func.(dir(func))
Поехали обсуждать сумасшедшие словари из вот этого странного теста.

Шаг 1:
True == 1 == 1.0

Пояснение:
Ну, почему, 1==1.0 - понятно

bool(False, True) в python работает точно также, как и числа 0 и 1. Правда если приводить их к строке, то вернутся 'False', 'True'

Это приводит к тому, что True и False можно использовать как 1 и 0.
Пример:
['no', 'yes'][True] == "yes"
['no', 'yes'][False] == "no"

Вывод:
Python считает 1, True, 1.0 - одинаковыми. А значит это один и тот же ключ словаря. Сравни hash()


Шаг 2:
Python вернет последнее значение и первый ключ
Пример:
>>> { 1.0: 'float', 1: 'int', True: 'boolean'}
{1.0: 'boolean'}
>>> {True: 'boolean', 1.0: 'float', 1: 'int'}
{True: 'int'}

А тут пояснение простое: значения обновляются последовательно, а ключ не меняется - это оптимизация python - зачем обновлять эквивалентные ключи.

Оно так всегда работало:
>>> {1: 'Первое значение', 1: 'Второе значение'}
{1: 'Второе значение'}

ДЗ
Разберитесь, как работает поиск значения в словаре(про хеш таблицы почитайте).
В этот раз мы решили создать задачку по-проще, но из нее развить тему серьезную.
Решайте задачу - потом выпустим кусочек интересной теории по set.
Как обычно - кто пользуется интерпретатором, век тому на паскале писать. Не используйте его!

set([set([1, 2, 3, 2]),
    set([2, 3, 4, 2, 3])])

Какие значения попадут в это множество?

{1, 2, 3, 4} - 23
👍👍👍👍👍👍👍👍 61%
{2, 3} - 1
👍 3%
{{1, 2, 3}, {2, 3, 4}} - 9
👍👍👍👍 24%
Тут ошибка - 5
👍👍👍 13%
👥 38 человек уже проголосовало.
Перешли С-подобному другу😉