# Абстракция списков

Абстракции - это та особенность Python, которой мне будет очень сильно недоставать, если я сменю язык программирования. Абстракции - это конструкторы, позволяющие создавать последовательности из других последовательностей. В Python (2 и 3) есть три типа подобных абстракций:

* абстракции списков
* абстракции словарей
* абстракции множеств
* абстракции генераторов

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

## `list` абстракции

Абстракции списков открывают доступ к простому и лаконичному синтаксису генерации списков. Конструкция состоит из квадратных скобок содержащих выражение и оператор `for`, плюс дополнительные `for` или `if` при необходимости. Выражения могут быть любыми, т.е. вам разрешается иметь любые элементы внутри списка. Результатом работы будет новый список после исполнения выражения с оглядкой на `for` и `if`.

**Шаблон использования:**

```python
variable = [out_exp for out_exp in input_list if out_exp == 2]
```

Вот короткий пример:

```python
multiples = [i for i in range(30) if i % 3 == 0]
print(multiples)
# Вывод: [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
```

Такой синтаксис может быть очень удобен для быстрого создания списков. Использование такого подхода вместо функции `filter` позволяет повысить читаемость кода (без потери скорости исполнения). Особенно хорошо абстракции списков заменяют создание нового простого списка при помощи цикла `for` и `append`. Наглядный пример:

```python
squared = []
for x in range(10):
    squared.append(x**2)
```

Вы можете сократить решение до одной строки:

```python
squared = [x**2 for x in range(10)]
```

## `dict` абстракции

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

```python
mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}

mcase_frequency = {
    k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0)
    for k in mcase.keys()
}

# mcase_frequency == {'a': 17, 'z': 3, 'b': 34}
```

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

```python
{v: k for k, v in some_dict.items()}
```

## `set` абстракции

Абстракции множеств схожи с абстракциями списков. Единственное различие - используются фигурные скобки `{}`. Вот пример:

```python
squared = {x**2 for x in [1, 1, 2]}
print(squared)
# Вывод: {1, 4}
```

## Абстракции генераторов

Абстракции генераторов похожи на абстракции списков. Единственное отличие - генераторы не выделяют память сразу под все элементы, а возвращают их один за одним, что намного более экономно:

```python
multiples_gen = (i for i in range(30) if i % 3 == 0)
print(multiples_gen)
# Output: <generator object <genexpr> at 0x7fdaa8e407d8>
for x in multiples_gen:
    print(x)
    # Outputs numbers
```

## Примечание

В русскоязычном сегменте интернета распространение получили другие названия абстракций, в частности используются понятия `генераторы списков/словарей/множеств`. Данные термины, однако, не совсем корректны, так как не являются генераторами (здесь возможна путаница с `genexp`, т.е. `(x**2 for x in [1, 2, 3])` - генераторное выражение, возвращающее объект генератора). В английском используется `list/dict/set comprehension` (`comprehension` - включение). Рекомендуется использовать либо вариант `списковые включения`, либо английское название или его краткую форму `listcomp`/`dictcomp`/`setcomp`.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://pavel-karateev.gitbook.io/intermediate-python/funkcionalnoe-programmirovanie/comprehensions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
