Трюк дня. Красивый вывод словарей с помощью json.dumps()
Стандартно пары ключей и значений в словаре выводятся в одну строку. В таком виде их тяжело читать:
>>> my_mapping = {'a': 23, 'b': 42, 'c': 0xc0ffee}
>>> my_mapping
{'b': 42, 'c': 12648430. 'a': 23}
Модуль json может справиться с этой задачей получше:
>>> import json
>>> print(json.dumps(my_mapping, indent=4, sort_keys=True))
{
"a": 23,
"b": 42,
"c": 12648430
}
Обратите внимание, что это работает только со словарями, содержащими примитивные типы:
>>> json.dumps({all: 'yup'})
TypeError: keys must be a string
#tips #tricks
Стандартно пары ключей и значений в словаре выводятся в одну строку. В таком виде их тяжело читать:
>>> my_mapping = {'a': 23, 'b': 42, 'c': 0xc0ffee}
>>> my_mapping
{'b': 42, 'c': 12648430. 'a': 23}
Модуль json может справиться с этой задачей получше:
>>> import json
>>> print(json.dumps(my_mapping, indent=4, sort_keys=True))
{
"a": 23,
"b": 42,
"c": 12648430
}
Обратите внимание, что это работает только со словарями, содержащими примитивные типы:
>>> json.dumps({all: 'yup'})
TypeError: keys must be a string
#tips #tricks
Трюк дня. Как поменять местами значения переменных
Допустим, нам нужно поменять местами значения переменных a и b.
a = 23
b = 42
"Классический" способ сделать это предполагает использование временной переменной:
tmp = a
a = b
b = tmp
Но Python также допускает использование короткой формы:
a, b = b, a
#tips #tricks
Допустим, нам нужно поменять местами значения переменных a и b.
a = 23
b = 42
"Классический" способ сделать это предполагает использование временной переменной:
tmp = a
a = b
b = tmp
Но Python также допускает использование короткой формы:
a, b = b, a
#tips #tricks
Трюк дня. Одновременная проверка нескольких флагов
В Python проверить несколько флагов одновременно можно разными способами:
x, y, z = 0, 1, 0
if x == 1 or y == 1 or z == 1:
print('passed')
if 1 in (x, y, z):
print('passed')
Следующие два способа подходят только для проверки на истинность:
if x or y or z:
print('passed')
if any((x, y, z)):
print('passed')
#tips
В Python проверить несколько флагов одновременно можно разными способами:
x, y, z = 0, 1, 0
if x == 1 or y == 1 or z == 1:
print('passed')
if 1 in (x, y, z):
print('passed')
Следующие два способа подходят только для проверки на истинность:
if x or y or z:
print('passed')
if any((x, y, z)):
print('passed')
#tips
Трюк дня. Распаковка аргументов функции
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
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
Трюк дня. Лямбда-функции
В Python есть ключевое слово lambda, позволяющее коротко объявлять маленькие и анонимные функции:
>>> add = lambda x, y: x + y
>>> add(5, 3)
8
Лямбда-функции состоят из одного выражения, причем они не обязательно привязаны к какому-нибудь имени (могут быть анонимными). Лямбда-функции всегда содержат неявный
Ту же самую функцию add() можно было бы объявить при помощи ключевого слова def:
>>> def add(x, y):
return x + y
>>> add(5, 3)
8
Так что же такого особенного в lambda? Лямбда-функции являются «функциональными выражениями»:
>>> (lambda x, y: x + y)(5, 3)
8
#tips
В Python есть ключевое слово lambda, позволяющее коротко объявлять маленькие и анонимные функции:
>>> add = lambda x, y: x + y
>>> add(5, 3)
8
Лямбда-функции состоят из одного выражения, причем они не обязательно привязаны к какому-нибудь имени (могут быть анонимными). Лямбда-функции всегда содержат неявный
return
.Ту же самую функцию add() можно было бы объявить при помощи ключевого слова def:
>>> def add(x, y):
return x + y
>>> add(5, 3)
8
Так что же такого особенного в lambda? Лямбда-функции являются «функциональными выражениями»:
>>> (lambda x, y: x + y)(5, 3)
8
#tips
Трюк дня. Встроенные методы Python: globals() и locals()
"globals()" возвращает словарь со всеми глобальными переменными в текущей области видимости:
>>> globals()
{...}
"locals()" делает то же самое, но для всех локальных переменных в текущей области видимости:
>>> locals()
{...}
#tips
"globals()" возвращает словарь со всеми глобальными переменными в текущей области видимости:
>>> globals()
{...}
"locals()" делает то же самое, но для всех локальных переменных в текущей области видимости:
>>> locals()
{...}
#tips
Трюк дня. Использование срезов без указания индексов
В Python синтаксис срезов списков допускает отсутствие индексов. Это можно применить с пользой:
Можно очистить список от всех элементов:
>>> lst = [1, 2, 3, 4, 5]
>>> del lst[:]
>>> lst
[]
Можно заменить все элементы списка, не создавая новый объект:
>>> a = lst
>>> lst[:] = [7, 8, 9]
>>> lst
[7, 8, 9]
>>> a
[7, 8, 9]
>>> a is lst
True
Можно также создать копию списка (поверхностную):
>>> b = lst[:]
>>> b
[7, 8, 9]
>>> b is lst
False
#tips
В Python синтаксис срезов списков допускает отсутствие индексов. Это можно применить с пользой:
Можно очистить список от всех элементов:
>>> lst = [1, 2, 3, 4, 5]
>>> del lst[:]
>>> lst
[]
Можно заменить все элементы списка, не создавая новый объект:
>>> a = lst
>>> lst[:] = [7, 8, 9]
>>> lst
[7, 8, 9]
>>> a
[7, 8, 9]
>>> a is lst
True
Можно также создать копию списка (поверхностную):
>>> b = lst[:]
>>> b
[7, 8, 9]
>>> b is lst
False
#tips
Трюк дня. Как соединить два словаря
В Python 3.5+:
>>> x = {'a': 1, 'b': 2}
>>> y = {'b': 3, 'c': 4}
>>> z = {**x, **y}
>>> z
{'c': 4, 'a': 1, 'b': 3}
В Python 2.x :
>>> z = dict(x, **y)
>>> z
{'a': 1, 'c': 4, 'b': 3}
В этих примерах Python мержит ключи словарей в порядке, указанном в выражении. При этом дубликаты перезаписываются слева направо.
#tips
В Python 3.5+:
>>> x = {'a': 1, 'b': 2}
>>> y = {'b': 3, 'c': 4}
>>> z = {**x, **y}
>>> z
{'c': 4, 'a': 1, 'b': 3}
В Python 2.x :
>>> z = dict(x, **y)
>>> z
{'a': 1, 'c': 4, 'b': 3}
В этих примерах Python мержит ключи словарей в порядке, указанном в выражении. При этом дубликаты перезаписываются слева направо.
#tips
Трюк дня. Символы Unicode в именах переменных
Python 3 позволяет использовать символы Unicode в именах переменных:
>>> π = math.pi
>>> class Spin̈alTap: pass
>>> Spin̈alTap()
<Spin̈alTap object at 0x10e58d908>
Но допускаются только буквенные символы:
>>> 🍺 = "beer"
SyntaxError:
"invalid character in identifier"
Это точно не стоит использовать в продакшене, но для личных экспериментов может быть интересно.
#tips
Python 3 позволяет использовать символы Unicode в именах переменных:
>>> π = math.pi
>>> class Spin̈alTap: pass
>>> Spin̈alTap()
<Spin̈alTap object at 0x10e58d908>
Но допускаются только буквенные символы:
>>> 🍺 = "beer"
SyntaxError:
"invalid character in identifier"
Это точно не стоит использовать в продакшене, но для личных экспериментов может быть интересно.
#tips
Трюк дня. Получение имени класса и функции
Имя класса объекта можно получить в виде строки:
>>> class MyClass: pass
>>> obj = MyClass()
>>> obj.class.name
'MyClass'
Аналогично с функциями:
>>> def myfunc(): pass
>>> myfunc.name
'myfunc'
#tips
Имя класса объекта можно получить в виде строки:
>>> class MyClass: pass
>>> obj = MyClass()
>>> obj.class.name
'MyClass'
Аналогично с функциями:
>>> def myfunc(): pass
>>> myfunc.name
'myfunc'
#tips
Трюк дня. Встроенный метод issubclass()
При помощи встроенного метода "issubclass()" можно проверить отношения наследования для класса:
>>> class BaseClass: pass
>>> class SubClass(BaseClass): pass
>>> issubclass(SubClass, BaseClass)
True
>>> issubclass(SubClass, object)
True
>>> issubclass(BaseClass, SubClass)
False
#tips
При помощи встроенного метода "issubclass()" можно проверить отношения наследования для класса:
>>> class BaseClass: pass
>>> class SubClass(BaseClass): pass
>>> issubclass(SubClass, BaseClass)
True
>>> issubclass(SubClass, object)
True
>>> issubclass(BaseClass, SubClass)
False
#tips
Трюк дня. Использование нескольких
**kwargs
Python 3.5+ позволяет передавать в функцию несколько наборов именованных аргументов ("kwargs") в рамках одного вызова с использованием синтаксиса **
:>>> def process_data(a, b, c, d):#tips
>>> print(a, b, c, d)
>>> x = {'a': 1, 'b': 2}
>>> y = {'c': 3, 'd': 4}
>>> process_data(**x, **y)
1 2 3 4
>>> process_data(**x, c=23, d=42)
1 2 23 42
Трюк дня. Проверка элементов списка на равенство
"Питоничные" способы проверить, все ли элементы в списке равны между собой:
Например, решение len(set()) - идиоматично, однако использование множества менее эффективно по части памяти и скорости работы.
#tips
"Питоничные" способы проверить, все ли элементы в списке равны между собой:
>>> lst = ['a', 'a', 'a']Решения расположены в порядке от наиболее до наименее "питоничных" и одновременно от наименее до наиболее эффективных.
>>> len(set(lst)) == 1
True
>>> all(x == lst[0] for x in lst)
True
>>> lst.count(lst[0]) == len(lst)
True
Например, решение len(set()) - идиоматично, однако использование множества менее эффективно по части памяти и скорости работы.
#tips
Трюк дня. Модуль ipaddress: работа с IP-адресами
В стандартной библиотеке Python 3 есть специальный модуль для работы с IP-адресами:
#tips
В стандартной библиотеке Python 3 есть специальный модуль для работы с IP-адресами:
>>> import ipaddressУзнать больше можно в документации: на английском, на русском.
>>> ipaddress.ip_address('192.168.1.2')
IPv4Address('192.168.1.2')
>>> ipaddress.ip_address('2001:af3::')
IPv6Address('2001:af3::')
#tips
Трюк дня. contextlib.suppress()
В Python 3.4+ можно использовать
В Python 3.4+ можно использовать
contextlib.suppress()
для выборочного игнорирования отдельных исключений:import contextlibЭто эквивалентно следующему коду:
with contextlib.suppress(FileNotFoundError):
os.remove('somefile.tmp')
try:#tips
os.remove('somefile.tmp')
except FileNotFoundError:
pass
Трюк дня. Звездочка в списке параметров функции
В Python 3 можно использовать звездочку "*" в списке параметров функции, чтобы следующие за ней параметры считались обязательными именованными аргументами:
>>> def f(a, b, *, c='x', d='y', e='z'):
return 'Hello'
Чтобы передать значения для c, d и e, вам придется явно задать их в виде пар "ключ=значение":
>>> f(1, 2, 'p', 'q', 'v')
TypeError:
"f() takes 2 positional arguments but 5 were given"
>>> f(1, 2, c='p', d='q',e='v')
'Hello'
Укажем именованные аргументы без значений по умолчанию и увидим, что они обязательны:
>>> def f(a, b, *, c, d, e):
return 'Hello'
>>> f(1, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() missing 3 required keyword-only arguments: 'c', 'd', and 'e'
#tips
В Python 3 можно использовать звездочку "*" в списке параметров функции, чтобы следующие за ней параметры считались обязательными именованными аргументами:
>>> def f(a, b, *, c='x', d='y', e='z'):
return 'Hello'
Чтобы передать значения для c, d и e, вам придется явно задать их в виде пар "ключ=значение":
>>> f(1, 2, 'p', 'q', 'v')
TypeError:
"f() takes 2 positional arguments but 5 were given"
>>> f(1, 2, c='p', d='q',e='v')
'Hello'
Укажем именованные аргументы без значений по умолчанию и увидим, что они обязательны:
>>> def f(a, b, *, c, d, e):
return 'Hello'
>>> f(1, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() missing 3 required keyword-only arguments: 'c', 'd', and 'e'
#tips
Трюк дня. Подсчет элементов в итерируемом объекте
collections.Counter позволяет находить наиболее часто встречающиеся элементы в итерируемом объекте:
collections.Counter позволяет находить наиболее часто встречающиеся элементы в итерируемом объекте:
>>> import collections#tips
>>> c = collections.Counter('helloworld')
>>> c
Counter({'l': 3, 'o': 2, 'e': 1, 'd': 1, 'h': 1, 'r': 1, 'w': 1})
>>> c.most_common(3)
[('l', 3), ('o', 2), ('e', 1)]
Трюк дня. Блок else в циклах for и while
В Python циклы for и while могут содержать блок else, который выполнится, только если цикл завершится без применения break.
#tips
В Python циклы for и while могут содержать блок else, который выполнится, только если цикл завершится без применения break.
#tips