26 July 2018

Аналоги в Python и JavaScript. Часть третья

PythonJavaScript
Original author: Aidas Bendoraitis a.k.a. archatas

Продолжаем перевод серии статей про аналоги в Python и JavaScript


В прошлых выпусках мы опирались на синтаксис классических версий Питона (2.7) и JS на основе ECMAScript 5. В этот раз мы будем использовать новые функции которые появились в Питоне 3.6 и JS стандарта ECMAScript 6.


ECMAScript 6 — относительно новый стандарт поддерживаемый большинством современных браузеров. Для использования стандарта 6 в старых браузерах вам понадобиться Babel для перевода современных конструкций JS6 на кросс-браузерную поддержку.


В сегодняшней статье: переменные в строках, распаковка списков, лямбда-функции, итерирование без индексов, генераторы и множества (sets).


Содержание других выпусков:


  1. Первая часть — приведение к типу, тернарный оператор, доступ к свойству по имени свойства, словари, списки, строки, конкатенация строк
  2. Вторая часть — сериализация словарей, JSON, регулярки, ошибки и исключения.
  3. Эта статья
  4. Четвертая часть — аргументы функций, создание и работа с классами, наследование, геттеры-сеттеры и свойства класса.

Переменные в строках


Традиционный способ построения строк с переменными использует конкатенацию строк и переменных:


name = 'World'
value = 'Hello, ' + name + '!\nWelcome!'

Такая запись может показаться разбросанной и плохочитаемой, также часто можно ошибиться в пробелах окружающих слова в строках.


Начиная с версии 3.6 в Питоне и в JS ECMAScrip6 вы можете использовать строковую интерполяцию, или, в терминах Питона — f-строки. Это строковые шаблоны в которых подставляются значения из переменных.


В Питоне f-строки помечаются символом f перед кавычками:


name = 'World'
value = f"""Hello, {name}!
Welcome!"""

price = 14.9
value = f'Price: {price:.2f} €'  # 'Price: 14.90 €'

В JS строковые шаблоны начинаются и кончаются обратной кавычкой (backtrick) `


name = 'World';
value = `Hello, ${name}!
Welcome!`;

price = 14.9;
value = `Price ${price.toFixed(2)} €`;  // 'Price: 14.90 €'

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


Распаковка списков


В Питоне, а теперь уже и в JS существует интересная возможность присвоить элементы последовательности различным переменным. К примеру, мы можем присвоить трем переменным три значения из списка:


[a, b, c] = [1, 2, 3]

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


a = 1
b = 2
a, b = b, a   # поменяли значения

В JS6+ также возможно:


a = 1;
b = 2;
[a, b] = [b, a];  // поменяли значения

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


first, second, *the_rest = [1, 2, 3, 4]
# first == 1
# second == 2
# the_rest == [3, 4]

Такое же можно сделать и в JS (ECMAScrip6):


[first, second, ...the_rest] = [1, 2, 3, 4];
// first === 1
// last === 2
// the_rest === [3, 4]

Лямбда-функции


И Питон и JS имеют довольно ясную функциональность для создания однострочных функций. Такие функции называются лямбда-функциями. Лямбды это такие функции которые принимают один или более аргументов и возвращают вычисленное значение. Обычно лямбда-функции используются когда нужно передать одну функцию в другую функцию в качестве колбека или в случае когда необходимо обработать каждый элемент последовательности.


В Питоне можно определить лямбда-функцию используя ключевое слово lambda:


sum = lambda x, y: x + y
square = lambda x: x ** 2

В JS используется => нотация. Если аргументов больше одного, они помещаются в скобки:


sum = (x, y) => x + y;
square = x => Math.pow(x, 2);

Итерация без индексов


Многие ЯП позволяют обходить массивы только используя доступ к определенному элементу по номеру индекса и циклу с инкрементом этого индекса.


for (i=0; i<items.length; i++) {
    console.log(items[i]);
}

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


for item in ['A', 'B', 'C']:
    print(item)

В современном JS такое реализуется при помощи оператора for..of:


for (let item of ['A', 'B', 'C']) {
    console.log(item);
}

Также можно обойти строку посимвольно в Питоне:


for character in 'ABC':
    print(character)

И в современном JavaScript:


for (let character of 'ABC') {
    console.log(character);
}

Генераторы


И Питон и современный JS позволяют определить специальные функции которые будут выглядеть как итераторы. При каждом вызове (итерации) они будут возвращать следующее сгенерированное значение из последовательности. Такие функции называются генераторы.


Генераторы обычно используют чтобы получить: числа из диапазона, строки из файла, данные постранично из внешнего API, числа фибоначчи и другие динамически генерируемые последовательности.


Технически генераторы выглядят как обычные функции, но вместо того чтобы вернуть одно значение (и прекратить работу), они выдают одно значение и приостанавливают работу до следующего вызова. Они будут генерировать следующие значения из списка при каждом вызове пока не будет достигнут конец списка.


Рассмотрим пример на Питоне в котором создается генератор countdown() который возвращает числа от заданного числа до 1 в обратном порядке (10,9,8,...,1):


def countdown(counter):
    while counter > 0:
        yield counter
        counter -= 1

for counter in countdown(10):
    print(counter)

То же самое можно получить в современном JS, но обратите внимание на * в описании функции. Это определяет ее как генератор:


function* countdown(counter) {
    while (counter > 0) {
        yield counter;
        counter--;
    }
}
for (let counter of countdown(10)) {
    console.log(counter);
}

Множества (Sets)


Мы уже познакомились со списками (lists), кортежами (tuples), массивами (arrays). Но есть еще один тип данных — множества (sets). Множества это массивы данных в котором каждый уникальный элемент присутствует только в единственном экземпляре. Теория множеств определяет с множествами такие операции как объединение(union), пересечение(intersection), и разность(difference), но мы не будем сейчас их рассматривать.


Создаем множество, добавляем в него элемент, проверяем существование элемента, получаем общее количество элементов, обходим множество по элементам и удаляем один элемент используя Питон:


s = set(['A'])
s.add('B'); s.add('C')
'A' in s
len(s) == 3
for elem in s:
    print(elem)
s.remove('C')

То же самое на JS:


s = new Set(['A']);
s.add('B').add('C');
s.has('A') === true;
s.size === 3;
for (let elem of s.values()) {
    console.log(elem);
}
s.delete('C')

Подытожим


  • Строковые шаблоны (f-строки) позволяют улучшить читаемость и упростить код, даже в случае многострочных объектов.
  • Можно обходить массивы, группы или строки без использования индексов.
  • Используя генераторы можно получить последовательности с практически неограниченным числом элементов.
  • Использование множеств упрощает проверку уникальности элемента в массиве.
  • Используйте лямбды когда вам нужны небольшие однострочные функции.

В следующей части поговорим об аргументах функций, классах, наследовании и свойствах.

Tags:pythonjavascriptдля начинающихперевод
Hubs: Python JavaScript
+9
4.6k 47
Comments 8