# Списки в Python (list): методы, срезы, сортировка, append, кортежи и множества

URL: https://skillaria.top/ru/guides/python/spiski-python

Список в Python (list) — упорядоченная изменяемая коллекция любых значений в квадратных скобках, например [250, 1200, 99]: элементы можно добавлять методом append, вставлять, удалять, брать срезами и сортировать. Метод sort сортирует список на месте и возвращает None, а функция sorted возвращает новый отсортированный список.

Список в Python (`list`) — это упорядоченный набор любых значений в квадратных скобках, который можно менять: добавлять элементы в конец, вставлять в середину, удалять, сортировать. Это самая ходовая коллекция языка: строки файла, траты за месяц, ответы API — почти всё начинается со списка. Разберём python list целиком: создание, методы, срезы, сортировку, генераторы списков, копирование, а в конце — кортежи и множества.

## Что такое список в Python

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

```
amounts = [250, 1200, 99]
print(amounts[0])     # 250 — первый элемент
print(amounts[-1])    # 99 — последний
amounts[1] = 1300     # список изменяемый
print(len(amounts))   # 3 — длина списка
```

Размер списка возвращает функция `len()`. Обращение к несуществующему индексу даст `IndexError: list index out of range`.

## Создание списка

```
empty = []                       # пустой список
also_empty = list()              # то же через функцию list
nums = [1, 2, 3]
chars = list("abc")              # ['a', 'b', 'c']
digits = list(range(5))          # [0, 1, 2, 3, 4]
zeros = [0] * 4                  # [0, 0, 0, 0]
```

Функция `list()` превращает в список любой итерируемый объект: строку, `range`, множество, ключи словаря.

## append и другие методы списков

Метод `append` добавляет один элемент в конец списка — это самый частый метод в Python. Он меняет список на месте и возвращает `None`.

```
amounts = [250, 1200]
amounts.append(450)          # [250, 1200, 450]
amounts.extend([10, 20])     # [250, 1200, 450, 10, 20]
amounts.insert(0, 5)         # [5, 250, 1200, 450, 10, 20]
amounts.remove(1200)         # удалить первое значение 1200
last = amounts.pop()         # 20 — удалить и вернуть последний
```

Частая ошибка: `a.append([10, 20])` добавит один элемент — вложенный список, а не два числа. Для нескольких элементов нужен `extend`.

| Метод | Что делает |
| --- | --- |

| `append(x)` | добавить x в конец |

| `extend(iter)` | добавить все элементы последовательности |

| `insert(i, x)` | вставить x перед индексом i |

| `remove(x)` | удалить первое вхождение x (ValueError, если нет) |

| `pop(i=-1)` | удалить и вернуть элемент по индексу |

| `index(x)` | индекс первого вхождения |

| `count(x)` | сколько раз встречается x |

| `sort()` | отсортировать на месте |

| `reverse()` | развернуть на месте |

| `copy()` | поверхностная копия |

| `clear()` | очистить список |

Удалить элемент по индексу или целый диапазон можно и оператором `del`: `del a[0]`, `del a[1:3]`. Полезные встроенные функции для списков: `len`, `sum`, `min`, `max`, `sorted`, `reversed`, `enumerate`, `zip`.

## Срезы в Python

Срез берёт часть списка по схеме `a[start:stop:step]`: от `start` включительно до `stop` не включительно с шагом `step`. Любую часть можно опустить. Срез всегда возвращает новый список.

```
a = [0, 1, 2, 3, 4, 5]
print(a[1:4])     # [1, 2, 3]
print(a[:2])      # [0, 1] — первые два
print(a[-2:])     # [4, 5] — последние два
print(a[::2])     # [0, 2, 4] — каждый второй
print(a[::-1])    # [5, 4, 3, 2, 1, 0] — развёрнутый
print(a[:])       # копия всего списка
```

В отличие от индекса, срез за пределами списка не вызывает ошибку: `a[10:20]` просто вернёт `[]`. Срезу можно присвоить значение и заменить кусок списка: `a[1:3] = ["x", "y", "z"]`.

### Срез строки

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

```
s = "Python 3.15"
print(s[:6])      # Python
print(s[-4:])     # 3.15
print(s[::-1])    # 51.3 nohtyP
```

Строку срезом изменить нельзя — строки неизменяемы, срез создаёт новую строку.

## Сортировка списка: sort и sorted

Это место, где новички путаются чаще всего. Метод `sort` переставляет элементы в самом списке и возвращает `None`. Функция `sorted` не трогает исходный список и возвращает новый отсортированный.

```
amounts = [250, 1200, 99]
amounts.append(450)
print(sorted(amounts))     # [99, 250, 450, 1200] — новая копия
print(amounts)             # [250, 1200, 99, 450] — исходный цел

result = amounts.sort()    # сортирует на месте
print(result, amounts)     # None [99, 250, 450, 1200]
```

Отсюда классическая ошибка «почему у меня None»: `a = a.sort()` затирает список значением `None`. Пишите либо `a.sort()`, либо `a = sorted(a)`.

### Ключ и обратный порядок

Оба варианта принимают параметры `key` и `reverse`. `key` — функция, по результату которой сравниваются элементы.

```
words = ["кофе", "Такси", "абонемент"]
print(sorted(words, key=len))               # ['кофе', 'Такси', 'абонемент']
print(sorted(words, key=str.lower))         # без учёта регистра
print(sorted([3, 1, 2], reverse=True))      # [3, 2, 1]

expenses = [("Еда", 650), ("Кино", 120), ("Такси", 300)]
expenses.sort(key=lambda e: e[1])           # по сумме
```

Сортировка в Python стабильна: элементы с одинаковым ключом сохраняют исходный порядок. Отличие ещё и в применимости: `sorted` принимает любую последовательность (строку, словарь, множество), а `sort` есть только у списков.

## Перевернуть список

Три способа с разным поведением:

- `a.reverse()` — разворачивает на месте, возвращает `None`;
- `a[::-1]` — новый развёрнутый список;
- `reversed(a)` — ленивый итератор, удобен в цикле: `for x in reversed(a):`.

## Перебор списка

```
items = ["кофе", "метро", "кино"]
for item in items:
    print(item)

for i, item in enumerate(items, start=1):
    print(i, item)          # 1 кофе, 2 метро, 3 кино

print("кино" in items)      # True — проверка вхождения
```

Не удаляйте элементы из списка, по которому идёт цикл, — часть элементов будет пропущена. Соберите новый список генератором или перебирайте копию `a[:]`.

## Генератор списков (list comprehension)

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

```
squares = [n * n for n in range(6)]          # [0, 1, 4, 9, 16, 25]
big = [a for a in [250, 1200, 99] if a > 200]  # [250, 1200]
names = [s.strip().title() for s in [" анна ", "олег"]]
```

Генераторы списков обычно быстрее и читаемее цикла с `append`. Но если логика не помещается в одну понятную строку, честный цикл лучше.

## Объединение, сложение и вычитание списков

```
a = [1, 2, 3]
b = [3, 4]
print(a + b)       # [1, 2, 3, 3, 4] — новый список
a += b             # как a.extend(b)
print([*a, *b])    # распаковка в новый список
```

Вычитания списков оператором `-` нет. Чтобы убрать из одного списка элементы другого, используйте генератор: `[x for x in a if x not in set(b)]`. Пересечение списков удобнее всего найти через множества: `set(a) & set(b)` (порядок и дубликаты при этом теряются).

## Вложенные и двумерные списки

Список списков — простой способ хранить таблицу или матрицу:

```
matrix = [[1, 2, 3], [4, 5, 6]]
print(matrix[1][2])     # 6
grid = [[0] * 3 for _ in range(2)]   # правильно
bad = [[0] * 3] * 2                  # ловушка: две ссылки на один список
bad[0][0] = 9
print(bad)              # [[9, 0, 0], [9, 0, 0]]
```

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

```
first, second, third = [10, 20, 30]
head, *rest = [1, 2, 3, 4]      # head=1, rest=[2, 3, 4]
print(*["a", "b"], sep=", ")    # a, b — print списка без скобок
```

Если число переменных не совпадает с длиной списка, будет `ValueError` — выручает звёздочка.

## Копирование списка

`b = a` не копирует список, а вешает второй ярлык на тот же объект: изменения через `b` видны в `a`. Независимую копию делают явно: `a.copy()`, `list(a)` или `a[:]`. Для вложенных данных этого мало — внутренние списки останутся общими, нужен `copy.deepcopy(a)`.

```
import copy
a = [[1, 2], [3]]
b = a.copy()
b[0].append(99)
print(a)                 # [[1, 2, 99], [3]] — вложенный список общий
c = copy.deepcopy(a)     # полностью независимая копия
```

## Кортежи: неизменяемый список

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

```
expense = (250, "Кофе")
amount, item = expense
expense[0] = 300
# TypeError: 'tuple' object does not support item assignment
```

Кортеж из неизменяемых значений хешируем, поэтому годится ключом словаря. Кортеж из одного элемента пишется с запятой: `(5,)`.

## Множества: только уникальное

Множество (`set`) хранит только уникальные значения и не помнит порядок. Это самый быстрый способ убрать дубликаты и проверить «есть ли такой элемент», а ещё оно умеет пересечение, объединение и разность.

```
jan = {"Еда", "Такси", "Кино"}
feb = {"Еда", "Подписки"}
print(jan & feb)    # {'Еда'}
print(feb - jan)    # {'Подписки'}
unique = list(dict.fromkeys([3, 1, 3, 2]))   # [3, 1, 2] — без дублей, порядок сохранён
empty = set()       # {} — это пустой dict!
```

## Какую коллекцию выбрать

| Задача | Коллекция |
| --- | --- |

| Порядок и изменения | `list` |

| Фиксированная запись | `tuple` |

| Поиск по ключу | `dict` |

| Уникальность, проверка «есть ли» | `set` |

| Неизменяемые настройки | `frozendict` (Python 3.15) |

Проверка `x in list` перебирает элементы по очереди, а `x in set` работает почти мгновенно. Если в цикле много раз проверяете вхождение в большой список, превратите его во множество.

## Итог

Python list — упорядоченная изменяемая коллекция: `append` и `extend` добавляют, `pop` и `remove` удаляют, срезы `a[start:stop:step]` берут части, `sort` сортирует на месте и возвращает `None`, а `sorted` отдаёт новый список. Копию делайте явно, для фиксированных записей берите кортеж, для уникальных значений — множество. Списки, кортежи, словари и множества разобраны на практике в курсе «Python 3.15: от новичка до профи».

## FAQ

**Чем список отличается от массива в Python?**

Встроенного массива в смысле других языков в Python нет, его роль играет список, который может хранить значения разных типов. Для компактных числовых массивов есть модуль array и библиотека NumPy.

**Как найти индекс элемента в списке?**

Метод a.index(x) возвращает индекс первого вхождения и бросает ValueError, если элемента нет. Поэтому перед вызовом стоит проверить x in a.

**Как удалить дубликаты из списка с сохранением порядка?**

Используйте list(dict.fromkeys(a)): словарь хранит ключи уникальными и в порядке вставки. Вариант list(set(a)) тоже убирает дубли, но порядок не сохраняет.

**Как объединить список строк в одну строку?**

Методом строки join: ", ".join(["a", "b", "c"]) даст "a, b, c". Все элементы должны быть строками, числа сначала преобразуют через map(str, a).

**Можно ли хранить в списке элементы разных типов?**

Да, список может содержать числа, строки, другие списки и любые объекты одновременно. Но сортировать такой список без параметра key обычно нельзя — сравнение числа со строкой даст TypeError.


---
Source: Skillaria.Top (https://skillaria.top)
