ТОП-15 трюков в Python 3, делающих код понятнее и быстрее

МЕНЮ


Искусственный интеллект
Поиск
Регистрация на сайте
Помощь проекту

ТЕМЫ


Новости ИИРазработка ИИВнедрение ИИРабота разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика

Авторизация



RSS


RSS новости


Подборка трюков в Python третьей версии, которая поможет вам при меньших усилиях писать более качественный программный код.

ТОП-15 трюков в Python 3, делающих код понятнее и быстрее

Python – язык программирования с ясным синтаксисом, и многие удобные вещи в силу простоты часто не задерживаются в памяти. При этом самые краткие и красивые решения обычно оказываются наиболее быстрыми. В представленной ниже подборке из 15 трюков в Python вы наверняка встретите приемы, знаний о которых не хватало в определенный момент в вашей практике.

Как бы вы решили задачу объединения списков разной длины без обхода элементов цикла? Вот как это можно сделать с помощью стандартной функции sum:

Python

1

2

L=[[1,2,3],[4,5],[6],[7,8,9]]

print(sum(L,[]))

1

[1,2,3,4,5,6,7,8,9]

Пусть и менее краткий, но более эффективный способ – применение модуля itertools:

1

2

3

4

import itertools

L=[[1,2,3],[4,5],[6],[7,8,9]]

print(list(itertools.chain.from_iterable(L)))

Заметим, что при работе с последовательностями многие полезные решения находятся в модулях стандартной библиотеки collections (контейнерные структуры данных) и itertools (операции над последовательностями). Внимательное прочтение документации модулей освободит вас от многих часов придумывания собственных «велосипедов».

Один из популярных трюков в Python – обмен значениями без создания временной переменной. Способ применим для любого числа переменных.

Python

1

2

3

4

a,b=1,2

print(a,b)

a,b=b,a

print(a,b)

1

2

12

21

В правой части инструкции присваивания последовательностей допускается указывать любые итерируемые объекты. Главное, чтобы число элементов слева равнялось числу элементов справа. Такое присваивание применяется и для сложных вложенных конструкций:

Python

1

2

for((a,b),c)in[((1,2),3),((4,5),6)]:

print(a,b,c)

1

2

123

456

Для указанного в подзаголовке случая в Python 3 есть оператор звездочки – расширенная операция распаковывания последовательности. Переменной со звездочкой присваивается часть списка, содержащая все неприсвоенные элементы, соответствующие этой позиции:

Python

1

2

3

4

5

6

7

8

9

10

11

seq=[1,2,3,4]

*a,b,c=seq

print(a,b,c)

a,*b,c=seq

print(a,b,c)

a,b,*c=seq

print(a,b,c)

a,b,c,*d=seq

print(a,b,c,d)

a,b,c,d,*e=seq

print(a,b,c,d,e)

1

2

3

4

5

[1,2]34

1[2,3]4

12[3,4]

123[4]

1234[]

Подобные операции можно осуществить и при помощи срезов, но такой код выглядит естественнее. Расширенную операцию распаковывания используют и в циклах, когда длина вложенных последовательностей варьируется:

Python

1

2

for(a,*b,c)in[(1,2,3),(4,5,6,7)]:

print(a,b,c)

1

2

1[2]3

4[5,6]7

В программном коде нередко приходится сталкиваться с конкатенацией строк при помощи знака сложения. Создание строки из списка нескольких подстрок удобнее осуществить при помощи строкового метода join:

Python

1

2

a=["Python","-","прекрасный","язык."]

print(" ".join(a))

Пример посложнее с методом join – конвертирование списка чисел в строку:

Python

1

2

numbers=[1,2,3,4,5]

print(', '.join(map(str,numbers)))

1

1,2,3,4,5

Проверить, являются ли строки анаграммами (например, в результате случайной перестановки букв) поможет класс Counter модуля collections:

Python

1

2

3

4

5

6

fromcollectionsimportCounter

str1='proglib'

str2='prgolib'

print(Counter(str1)==Counter(str2))

1

True

Чтобы поменять местами строки и столбцы матрицы, созданной с помощью встроенных типов данных, воспользуйтесь функцией zip:

Python

1

2

3

original=[('a','b'),('c','d'),('e','f')]

transposed=zip(*original)

print(list(transposed))

1

[('a','c','e'),('b','d','f')]

Если вы регулярно сталкиваетесь с подобными задачами, вместо таких трюков в Python принято использовать библиотеку NumPy.

Среди регулярно используемых трюков в Python – преобразование списка во множество и обратно в список для удаления повторяющихся элементов списка:

Python

1

2

items=[2,2,3,3,1]

print(list(set(items)))

1

[1,2,3]

Но множества – это неупорядоченные последовательности. Часто стоит задача сохранить порядок следования элементов. Для этого удобно воспользоваться типом данных OrderedDict из модуля collections:

Python

1

2

3

4

items=[2,2,3,3,1]

fromcollectionsimportOrderedDict

print(list(OrderedDict.fromkeys(items).keys()))

1

[2,3,1]

Иногда элементы if настолько просты, что кажется излишним тратить на них строки. В этом случае имеет смысл применить тернарный оператор if/else:

Python

1

A=YifXelseZ

Интерпретатор выполняет выражение Y, если объект X – истина, и Z, если X – ложь. Не злоупотребляйте этим выражением, если X, Y, Z имеют сложную форму записи.

Тернарный операторможно использовать не только для переменных, но и для функций:

Python

1

2

3

4

5

6

7

8

9

defproduct(a,b):

returna*b

defsummarize(a,b):

returna+b

c=True

print((product ifcelsesummarize)(3,4))

1

12

Следующая инструкция

Python

1

X=AorBorCorNone

присвоит переменной X первый непустой (имеющий истинное значение) объект из множества объектов A, B и С или None, если все предыдущие объекты окажутся пустыми. В простейшем виде эту особенность используют для задания значения по умолчанию:

Python

1

X=Aordefault

Аналогичным образом логический оператор and можно применять для нахождения первого ложного значения.

Обращение к несуществующему ключу словаря вызывает исключение. Избежать этого можно, вызывая метод get. В указанном случае метод выдает None (по умолчанию) или заданное значение аргумента.

Python

1

2

3

4

d={'a':1,'b':2}

print(d.get('c'))

print(d.get('c',3))

1

2

None

3

При создании собственного типа данных на основе словарей обратите внимание на метод __missing__ для возвращения аргумента при отсутствии ключа:

Python

1

2

3

4

5

6

7

8

classMyDict(dict):

def__missing__(self,key):

returnkey

D=MyDict(a=1,b=2)

print(D)

print(D['a'])

print(D['c'])

1

2

3

{'a':1,'b':2}

1

c

Часто указывается, что основное различие Python 2-й и 3-й версий – это скобки после инструкции print. Это же означает, что инструкция print стала функцией, а значит, скобки могут включать какие-то дополнительные аргументы.

Так и есть. В print имеются следующие аргументы:

  • строка sep (по умолчанию один пробел), вставляемая между объектами при выводе;
  • строка end (по умолчанию ), добавляемая в конец выводимого текста;
  • file (по умолчанию sys.stdout) – любой объект, поддерживающий метод файлов write(string), то есть стандартный поток, файл и др.

Например, если нам не нужно объединять подстроки, а лишь напечатать суммарную строку:

Python

1

2

forpart in["prog","lib",".io"," "]:

print(part,end='')

1

proglib.io

Тот же подход можно практиковать для чтения файлов:

Python

1

2

forline inopen('script.py'):

print(line,end='')

Присвоение аргументу end пустой строки приводит к тому, что строки файла не перемежаются пустыми строками. Иначе при чтении строк файла и использовании end по умолчанию символ окончания строки повторялся бы два раза.

Задача нумерации элементов последовательности настолько распространена, что в Python есть соответствующая встроенная функция enumerate:

Python

1

2

fori,item inenumerate(['a','b','c']):

print(i,item)

1

2

3

0a

1b

2c

Для тех, кто уже знаком с enumerate, может оказаться новостью, что у функции есть второй аргумент, задающий начальное число:

Python

1

2

fori,item inenumerate(['a','b','c'],1):

print(i,item)

1

2

3

1a

2b

3c

Распространена практика использования словарей в качестве таблиц для хранения данных. Сортировка данных словаря по значениям ключей, а не самим ключам, нередко ставит в тупик. Задача решается довольно просто при помощи соответствующего аргумента функции сортировки:

Python

1

2

d={'яблоки':40,'апельсины':80,'бананы':70}

print(sorted(d,key=d.get))

1

['яблоки','бананы','апельсины']

Вы, конечно, пользовались генераторами списков. Но знаете ли вы о генераторах множеств и словарей?

Python

1

2

3

4

S={i**2foriinrange(10)}

D={i:i**2foriinrange(10)}

print(S)

print(D)

1

2

{0,1,64,4,36,9,16,49,81,25}

{0:0,1:1,2:4,3:9,4:16,5:25,6:36,7:49,8:64,9:81}

В случае словарей отличие только в парах ключ-значение. Такие генераторы удобны для начальной инициализации значений последовательностей.

Найти самый часто повторяющийся элемент можно с помощью встроенной функции max. Функция max умеет искать наибольшее значение не только для самого итерируемого объекта, но и основываясь на результах применения к нему функции. Преобразовав список во множество (см. трюк 7) и использовав метод count для нахождения числа вхождений элемента в список, получаем:

Python

1

2

a=[1,2,3,1,2,3,2,2,4,5,1]

print(max(set(a),key=a.count))

1

2

Если необходимо найти несколько наиболее часто повторяющихся значений, воспользуйтесь счетчиком Counter из библиотеки collections:

Python

1

2

3

4

5

fromcollectionsimportCounter

a=[1,2,3,1,2,3,2,2,4,5,1]

cnt=Counter(a)

print(cnt.most_common(3))

1

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

Метод most_common выводит список кортежей вида (элемент, число повторений). Аргумент соответствует желаемому числу кортежей. По умолчанию выводится список кортежей для всех элементов переданного списка.

Наверняка вы знаете про Дзен Python, выводимый интерпретатором по команде import this. В третьей версии Python спрятаны и другие «пасхалки»:

Python

1

importantigravity

1

import __hello__


Источник: proglib.io

Комментарии: