Hello World – Telegram
Hello World
1.68K subscribers
71 photos
6 videos
3 files
161 links
Be so good that you cannot be ignored. And then, go one step beyond.
Download Telegram
Голосование закончено!
Сегодня мы разыграем код на PyCharm Professional, любезно предоставленный одним из наших подписчиков.
Победил: @a1*20

Всего участников: 46

Всем спасибо за участие! С победителем уже связались. Никнейм убрал на всякий случай.
Что выведут переменные a и b?
a = [1, 2]
b = a
a = a + [3, 4]
print(‘a =’, a)
print(‘b =’, b)
Правильный ответ:
a = [1, 2, 3, 4]
b = [1, 2]


Хорошо, но как вам такое?
a = [1, 2]
b = a
a += [3, 4]


Вывод:
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]


Объяснение:
▪️a += b не ведет себя так же, как a = a + b
▪️выражение a = a + [3, 4] генерирует новый объект и устанавливает ссылку a на этот новый объект, оставляя b неизменным
Форматирование списка
>>> l = [[1, 2, 3], [4, 5], [6], [7, 8, 9]]
>>> sum(l, [])
[1, 2, 3, 4, 5, 6, 7, 8, 9]


В функциональном стиле:
from functools import reduce
from operator import add
data = [[1, 2, 3], [4, 5, 6]]
reduce(add, data)


Вывод:
>>> data
[1, 2, 3, 4, 5, 6]


#tips
Использование переменной, не определенной в области
a = 42
def func1():
return a

def func2():
a += 1
return a


Вывод:
>>> func1()
42
>>> func2()
UnboundLocalError: local variable 'a' referenced before assignment


Объяснение:

▪️Когда ты назначаешь переменную в области видимости, она становится локальной. Таким образом, переменная a становится локальной для области func2, но поскольку она ранее не была инициализирована в той же области, возникает ошибка.
▪️Чтобы изменить внешнюю переменную области a в func2, используй ключевое слово global:
def func2()
global a
a += 1
return a


Вывод:
>>> func2()
43


#global
Return
def func():
try:
return 'try'
finally:
return 'finally’


Вывод:
>>> func()
'finally’


Объяснение:

▪️Когда в try-блоке «try … finally» выполняется оператор return, break или continue, finally также выполняется «на выходе».
▪️Возвращаемое значение функции определяется последним выполненным оператором return. Поскольку finally выполняется всегда, оператор return, выполняемый в finally, всегда будет последним.

#return
Вложенные list comprehensions

В list comprehensions можно использовать несколько for:
>>> l = [[1,2,3], [4,5,6]]
>>> [lll * 2 for ll in l for lll in ll]
[2, 4, 6, 8, 10, 12]


#tips
The random module

Нетрудно догадаться, что модуль random служит для генерации случайных чисел. В основу его работы положен алгоритм Мерсенна. Функция random.random() возвращает случайный float из интервала [0.0, 1.0). Результат всегда будет меньше чем 1.0.
>>> random.random()
0.4631297580529897
>>> random.random()
0.5855244248224873


Стоит рассмотреть два интересных примера использования функции random.

▪️Для того, чтобы выбрать рандомный элемент из списка или кортежа, используйте random.choice()
>>> items = ['one', 'two', 'three', 'four', 'five']
>>> random.choice(items)
’two’


▪️Для того, чтобы выбрать несколько элементов из списка или кортежа, используйте random.choices()
>>> random.choices(items, k=3)
['three', 'five', 'four’]


#random
Сортировка словаря по значению
>>> xs = {'a': 4, 'b': 3, 'c': 2, 'd': 1}
>>> sorted(xs.items(), key=lambda x: x[1])
[('d', 1), ('c', 2), ('b', 3), ('a', 4)]


Или c помощью operator:
>>> import operator
>>> sorted(xs.items(), key=operator.itemgetter(1))
[('d', 1), ('c', 2), ('b', 3), ('a', 4)]


#tips
Метод get для словарей
name_for_userid = {
382: "Alice",
590: "Bob",
951: "Dilbert",
}

def greeting(userid):
return "Hi {}".format(name_for_userid.get(userid, “there”))


Вывод:
>>> greeting(382)
"Hi Alice!”


Вызов функции с аргументом по умолчанию (или без существующего ключа):
>>> greeting(333333)
"Hi there!”


#tips #dict
type() vs isinstance()

С помощью функции type() можно проверить, принадлежит ли аргумент тому или иному типу:
>>> a = 10
>>> b = [1, 2, 3]
>>> type(a) == int
True
>>> type(b) == list
True
>>> type(a) == float
False


В отличие от type(), функция isinstance() специально создана для проверки принадлежности данных определенному классу (типу данных):
>>> isinstance(a, int)
True
>>> isinstance(b, list)
True
>>> isinstance(b, tuple)
False
>>> c = (4, 5, 6)
>>> isinstance(c, tuple)
True


isinstance() по сравнению с type() позволяет проверить данные на принадлежность хотя бы одному типу из кортежа, переданного в качестве второго аргумента:
>>> isinstance(a, (float, int, str))
True
>>> isinstance(a, (list, tuple, dict))
False


Кроме того, isinstance() поддерживает наследование. Для isinstance() экземпляр производного класса также является экземпляром базового класса. Для type() это не так:
>>> class A (list):
... pass
...
>>> a = A()
>>> type(a) == list
False
>>> type(a) == A
True
>>> isinstance(a, A)
True
>>> isinstance(a, list)
True


#tips #isinstance
Мы с @python_lounge создали совместный чат для питонистов и для тех, что еще только начинает. В планах участники будут помогать друг другу с различными ошибками и просто отвечать на вопросы.

@pychat_ru - ждем всех.
Hello World pinned «Мы с @python_lounge создали совместный чат для питонистов и для тех, что еще только начинает. В планах участники будут помогать друг другу с различными ошибками и просто отвечать на вопросы. @pychat_ru - ждем всех.»
Namedtuples

Использование namedtuple немного короче, чем объявление класса напрямую:
>>> from collections import namedtuple
>>> Car = namedtuple('Car', 'color mileage anothernumber’)
>>> my_car = Car('red', 3812.4, 228)
>>> my_car.color
'red'
>>> my_car.mileage
3812.4
>>> my_car.anothernumber
228


Строковое представление нашего объекта:
>>> my_car
Car(color='red' , mileage=3812.4, anothernumber=228)


Как и обычный кортеж, namedtuple неизменяем:
>>> my_car.color = 'blue'
AttributeError: "can't set attribute”


#tips
Как работает цикл for в Python?

Python не имеет традиционных циклов for. Для того, чтобы объяснить это, рассмотрим цикл for написанный в C стиле:
int numbers[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < size; ++i) {
printf(“%d\n”, numbers[i]);
}


Так работает типичный цикл for в C-подобных языках программирования. Но цикл в Python так не работает. Цикл в Python это скорее foreach цикл.
numbers = [1, 2, 3, 4, 5]
for n in numbers:
print(n)


📎 В циклах Python нет индексной переменной
📎 Здесь нет инициализации индекса, проверки границ или инкрементации индекса
📎 Циклы в Python работают со всеми элементами листа
📎 Именно поэтому эти циклы могут работать с любыми итерируемыми объектами, например:
numbers = [1, 2, 3, 4, 5]
iterator = iter(numbers)
for item in iterator:
print(item)


#for #iterators #tips
Function argument unpacking

Создадим простую функцию.
def myfunc(x, y, z):
print(x, y, z)


Создадим к ней дополнительно кортеж и словарь.
tuple_vec = (1, 0, 1)
dict_vec = {'x': 1, 'y': 0, 'z': 1}


Теперь мы можем передавать их в нашу функцию вот так просто, это удобно:
>>> myfunc(*tuple_vec)
1, 0, 1


>>> myfunc(**dict_vec)
1, 0, 1


#tips
Есть ли разница между [] и list()?
>>> f = []
>>> f = list()


В принципе результат будет одним и тем же, но давайте заглянем глубже:
>>> timeit.timeit(‘[]’, number=10**8)
2.25569809000001
>>> timeit.timeit(‘list()’, number=10**8)
10.330681907999995


Инициализация листа с помощью конструктора list() выглядит как минимум в 4-5 раз медленнее. Попробуем заглянуть внутрь с помощью модуля dis, который служит для изучения байткода Python’a.
>>> dis.dis('f=[]')
1 0 BUILD_LIST 0
2 STORE_NAME 0 (f)
4 LOAD_CONST 0 (None)
6 RETURN_VALUE
>>> dis.dis('f=list()')
1 0 LOAD_NAME 0 (list)
2 CALL_FUNCTION 0
4 STORE_NAME 1 (f)
6 LOAD_CONST 0 (None)
8 RETURN_VALUE


Ответ заключается в том, что в то случае когда мы выбираем list() вместо [] мы теряем вычислительное время на “избыточный” вызов самой функции list().

📎 Во многих случаях это не настолько важно, поскольку мы имеем дело с микросекундами. Однако стоит об этом помнить, если ты имеешь дело с big data.

#list