[Перевод] 10 хитростей Python, о которых полезно знать

По данным StackOverflow Python — это самый быстрорастущий язык программирования. Например, в одном из отчётов Forbes речь идёт о том, что использование Python выросло на 456%. Python применяется в Netflix, в IBM, и ещё в тысячах компаний по всему миру. Давайте не забывать и о Dropbox. Сервисы этой компании тоже написаны на Python. В соответствии с исследованием Dice, знания в области Python весьма востребованы в наши дни, а индекс популярности языков программирования говорит о том, что Python — это сегодня самый популярный язык в мире. Если сравнить Python с другими языками, то окажется, что у него есть следующие сильные стороны:

  1. Совместимость с подавляющим большинством платформ и операционных систем.
  2. Наличие множества опенсорсных фреймворков и инструментов.
  3. Код, который легко читать и поддерживать.
  4. Надёжная стандартная библиотека.
  5. Стандартный механизм разработки через тестирование.


emfmbrsnnzvcnyj3ixcunacyhim.jpeg

Хитрости Python


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

▍1. Конкатенация строк


Если нужно конкатенировать список строк, сделать это можно в цикле for, по одной добавляя строки к итоговому результату. Однако такой подход будет весьма неэффективным, особенно в том случае, если список оказывается достаточно длинным. В Python строки являются иммутабельными сущностями. В результате каждая операция по конкатенации строк означает необходимость копирования пары строк в новую строку.

Более эффективный подход к решению этой задачи заключается в использовании функции join():

characters = ['p', 'y', 't', 'h', 'o', 'n']
word = "".join(characters)
print(word) # python


▍2. Использование генераторов списков


Генераторы списков используются для создания новых списков из других итерируемых объектов. Так как генератор возвращает списки, его описание представляет собой выражение, включённое в квадратные скобки, выполняемое для каждого элемента списка. Сюда же входит и описание цикла for, выполняющего проход по каждому элементу. Генераторы списков позволяют ускорить работу со списками за счёт того, что интерпретатор Python оптимизирован в расчёте на шаблоны, повторяющиеся при обходе списка.

В качестве примера рассмотрим нахождение квадратов первых пяти целых чисел с использованием генератора списков:

m = [x ** 2 for x in range(5)]
print(m) # [0, 1, 4, 9, 16]


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

list_a = [1, 2, 3, 4]
list_b = [2, 3, 4, 5]
common_num = [a for a in list_a for b in list_b if a == b]
print(common_num) # [2, 3, 4]


▍3. Итерирование списков с помощью enumerate ()


Метод enumerate() добавляет к итерируемой коллекции нумерацию и возвращает объект, генерирующий пары элементов, состоящие из индекса элемента и самого этого элемента.

Решим классическую задачу FizzBuzz, предлагаемую на собеседованиях. Вот условие этой задачи: «Напишите программу, которая выводит список чисел. При этом вместо чисел, кратных 3, выводится fizz, вместо чисел, кратных 5 — buzz, а вместо чисел, кратных и 3, и 5 — fizzbuzz».

numbers = [30, 42, 28, 50, 15]
for i, num in enumerate(numbers):
    if num % 3 == 0 and num % 5 == 0:
       numbers[i] = 'fizzbuzz'
    elif num % 3 == 0:
       numbers[i] = 'fizz'
    elif num % 5 == 0:
       numbers[i] = 'buzz'
print(numbers) # ['fizzbuzz', 'fizz', 28, 'buzz', 'fizzbuzz']


▍4. Использование функции zip () при работе со списками


Предположим, что вам нужно скомбинировать несколько списков одинаковой длины и вывести результирующий список. Как и в других случаях, подобную задачу можно решить, так сказать, «в лоб», а можно воспользоваться чем-то вроде универсальной функции zip():

countries = ['France', 'Germany', 'Canada']
capitals = ['Paris', 'Berlin', 'Ottawa']
for country, capital in zip(countries,capitals):
    print(country, capital) # France Paris 
                              Germany Berlin
                              Canada Ottawa


▍5. Использование модуля itertools


Python-модуль itertools представляет собой набор инструментов для работы с итераторами. В состав этого модуля входит множество средств для генерирования различных последовательностей. Здесь, в качестве примера, рассмотрим метод itertools.combinations(). Этот метод используется для создания комбинаций. Тут есть и средства для группировки входных значений.

Рассмотрим реальный пример для того чтобы разобраться в вышесказанном.

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

Взглянем на следующий код:

import itertools
friends = ['Team 1', 'Team 2', 'Team 3', 'Team 4']
list(itertools.combinations(friends, r=2)) # [('Team 1', 'Team 2'),      ('Team 1', 'Team 3'),  ('Team 1', 'Team 4'),  ('Team 2', 'Team 3'),  ('Team 2', 'Team 4'),  ('Team 3', 'Team 4')]


Здесь нужно обратить внимание на то, что порядок значений неважен. Так как комбинации ('Team 1', 'Team 2') и ('Team 2', 'Team 1') представляют собой одну и ту же пару команд, в итоговый список будет включена лишь одна из них. Похожим образом можно использовать и метод itertools.permutations(), и другие методы этого модуля. Подробное руководство по itertools можно найти здесь.

▍6. Использование коллекций Python


Коллекции Python — это контейнерные типы данных. В частности, это списки, множества, кортежи, словари. Модуль collections даёт в распоряжение разработчика высокопроизводительные типы данных, которые помогают улучшить код, сделать его чище и облегчить работу с ним. Этот модуль содержит множество полезных методов. Здесь мы рассмотрим метод Counter().

Этот метод принимает итерируемый объект, такой, как список или кортеж, и возвращает словарь, содержащий сведения о количестве различных объектов в исследуемом списке (Counter Dictionary). Ключами такого словаря являются уникальные элементы, представленные в итерируемом объекте, а значениями — количества таких элементов.

Для создания объекта Counter нужно передать итерируемый объект (список, например) методу Counter():

import collections 
count = collections.Counter(['a','b','c','d','b','c','d','b'])
print(count) # Counter({'b': 3, 'c': 2, 'd': 2, 'a': 1}) 


Подробности о модуле collections можно почитать здесь.

▍7. Преобразование двух списков в словарь


Предположим, у нас имеется два списка. Один из них содержит имена студентов, а второй — их оценки. Как преобразовать эти два списка в словарь? Если прибегнуть для этого к функции zip(), то данная задача может быть решена так:

students = ["Peter", "Julia", "Alex"]
marks = [84, 65, 77]
dictionary = dict(zip(students, marks))
print(dictionary) # {'Peter': 84, 'Julia': 65, 'Alex': 77}


▍8. Использование функций-генераторов


Функции-генераторы — это функции, которые ведут себя как итераторы. Они позволяют программисту быстро и легко создавать аккуратные итераторы. Рассмотрим пример, раскрывающий эту идею.

Предположим, что нам нужно найти сумму квадратов первых 100000000 целых чисел, начиная с 1.

Выглядит эта задача, вроде бы, несложно. Её без проблем можно решить с помощью генераторов списков. Однако проблема тут заключается в большом объёме входных данных. Взглянем на следующий код:

import time
t1 = time.clock()
sum([i * i for i in range(1, 100000000)])
t2 = time.clock()
time_diff = t2 - t1
print(f"It took {time_diff} Secs to execute this method") # It took 13.197494000000006 Secs to execute this method


Если нам нужно будет найти сумму квадратов для ещё большего количества чисел, то окажется, что эта методика для их поиска подходит плохо из-за того, что на поиск решения требуется очень много времени. В этой ситуации нам на помощь придут функции-генераторы Python. В нашем случае для того, чтобы перейти от использования генераторов списков к функциям-генераторам, достаточно поменять квадратные скобки в выражении генератора на круглые. Сделаем это и найдём время, необходимое для решения задачи:

import time
t1 = time.clock()
sum((i * i for i in range(1, 100000000)))
t2 = time.clock()
time_diff = t2 - t1
print(f"It took {time_diff} Secs to execute this method") # It took 9.53867000000001 Secs to execute this method


Как видно, теперь на решение той же задачи нужно заметно меньше времени. А при росте масштабов входных данных этот эффект окажется ещё более заметным.

Вот материал о функциях-генераторах.

▍9. Возврат из функции нескольких значений


В Python есть возможность возврата из функции нескольких значений. Этого нет во многих других популярных языках программирования. Для возврата из функции нескольких значений их нужно разделить запятыми. На основе этого списка значений Python создаст кортеж и вернёт его туда, откуда была вызвана функция. Вот пример:

def multiplication_division(num1, num2):
    return num1*num2, num1/num2
product, division = multiplication_division(15, 3)
print("Product =", product, "Quotient =", division) # Product = 45 Quotient = 5.0


▍10. Использование функции sorted ()


В Python очень легко сортировать некие последовательности данных с использованием встроенной функции sorted(), которая берёт на себя решение всех сопутствующих задач. Эта функция сортирует любые последовательности (списки, кортежи) и всегда возвращает список с отсортированными элементами. Рассмотрим пример сортировки списка чисел в порядке возрастания:

sorted([3,5,2,1,4]) # [1, 2, 3, 4, 5]


А вот — пример сортировки списка строк в порядке убывания:

sorted(['france', 'germany', 'canada', 'india', 'china'], reverse=True) # ['india', 'germany', 'france', 'china', 'canada']


Итоги


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

Уважаемые читатели! Просим опытных Python-разработчиков рассказать о полезных возможностях Python, которыми они регулярно пользуются.

u9qankiogj61jowwkrc-v8c8rgm.png


1ba550d25e8846ce8805de564da6aa63.png

© Habrahabr.ru