💀
Второй курс РПО
Разработка программных модулей
Разработка программных модулей
  • Модели разработки
  • Ошибки и отладка программ
  • Средства разработки алгоритмов
    • Основные принципы и стадии тестирования
  • Сложностные классы
  • Эмуляторы операционных систем
  • Сложность сортировки
  • Уровни тестирования
  • Задание №1
  • Регрессионное тестирование
  • Тестирование «белым ящиком»
  • Как делать оценку сложности?
  • Алгоритмы и сложность
  • Тестирование "белым ящиком" №2
  • Сложность алгоритмов
  • Тестирование "белым ящиком" №3
  • Тестирование "Чёрным ящиком»" №1
  • Тестирование "Черным ящиком" №2
  • Оценка сложности эвристических алгоритмов
  • Принципы ООП
  • Тестирование "Черным ящиком" №3
  • КТ - В3
  • Модульное тестирование
    • С кодами
  • Модульное тестирование
  • Абстрактные классы и интерфейсы в Python
  • Структуры в Python по аналогии с C++
    • Диалоги гениев
  • Делегаты в Python
    • Ещё более не смешные диалоги
  • Регулярные выражения в Python от простого к сложному
  • Python: Коллекции
  • Параметризованные классы (шаблоны)
  • Указатели и операции со списками в Python
  • Интеграционное тестирование
  • Работа с классами. Перегрузка методов
  • Определение операций в классе.
  • Создание наследованных классов
  • Интеграционное тестирование
  • Работа с объектами через интерфейсы
  • Использование стандартных интерфейсов
  • Работа с типом данных "Структура"
  • Коллекции. Параметризованные классы
  • Использование регулярных выражений
  • Операции со списками
  • Что такое паттерны проектирования?
  • Шпаргалка по шаблонам проектирования
    • [Habr] Шпаргалка
  • UML-диаграммы проектирования
  • Использование основных шаблонов.
  • Использование каких то там шаблонов
  • 15-я Практическая
  • 16-я Практическая
  • Graphviz Online
  • 17-я Практическая
  • Введение в теорию программирования: Объектно-ориентированный подход
  • Документирование софта и стандарты
  • C# Ввод и вывод
  • Оптимизация кода: просто о главном
  • Автоматизация разработки технической документации
  • Автоматизированное документирование и первичные данные
  • ADO.NET что это?
Powered by GitBook
On this page
  • Проблемы изучения коллекций
  • Типы коллекций
  • Классификация коллекций
  • Общие подходы работы с коллекциями
  • Методы для работы с коллекциями
  • Конвертация коллекций
  • Индексирование
  • Срезы
  • Сортировка
  • Обратный порядок
  • Объединение коллекций
  • Списки, кортежи и строки
  • Словари
  • Множества
  • Объединение с изменением исходной коллекции
  • Добавление и удаление элементов
  • Добавление элементов
  • Удаление элементов
  • Что такое генераторы?
  • Типы генераторов
  • Синтаксис генераторов
  • Выражения-генераторы
  • Особенности:
  • Генерация строк
  • Использование enumerate()
  • Частичный перебор
  • Преимущества генераторов

Python: Коллекции

17.01.2025

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


Проблемы изучения коллекций

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

Для кого эта статья? Для тех, кто знает основы Python и хочет упорядочить свои знания о коллекциях: списках, кортежах, строках, множествах и словарях.


Типы коллекций

Рассматриваются стандартные коллекции:

  • Список (list) — изменяемый, индексированный.

  • Кортеж (tuple) — неизменяемый, индексированный.

  • Строка (string) — неизменяемая, индексированная.

  • Множество (set, frozenset) — изменяемое/неизменяемое, неиндексированное, уникальные элементы.

  • Словарь (dict) — изменяемый, содержит пары ключ: значение.


Классификация коллекций

  1. Индексированность

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

  2. Уникальность

    • Во множестве элементы уникальны. Словари уникальны только по ключам.

  3. Изменяемость

    • Изменяемые коллекции (списки, множества, словари) позволяют добавлять, изменять и удалять элементы.

    • Неизменяемые (строки, кортежи, frozenset) не допускают изменений после создания.

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


Общие подходы работы с коллекциями

1. Печать содержимого

my_list = ['a', 'b', 'c']
my_dict = {'a': 1, 'b': 2}

print(my_list)  # ['a', 'b', 'c']
print(my_dict)  # {'a': 1, 'b': 2}

2. Подсчет элементов

Используется функция len():

len(my_list)  # 3
len(my_dict)  # 2

3. Проверка наличия элемента

print('a' in my_list)  # True
print('z' in my_dict)  # False

4. Итерация в цикле

Можно перебирать элементы коллекции с помощью for:

for item in my_list:
    print(item)

for key, value in my_dict.items():
    print(key, value)

Методы для работы с коллекциями

  • .count(): считает количество вхождений элемента (для списков, строк, кортежей).

  • .index(): возвращает индекс первого найденного элемента.

  • .copy(): делает копию коллекции.

  • .clear(): очищает коллекцию (для списков, словарей, множеств).


Конвертация коллекций

Любой тип коллекции можно преобразовать в другой:

  • Из кортежа в список: list(my_tuple)

  • Из списка в множество: set(my_list)

Пример:

my_tuple = ('a', 'b', 'a')
my_set = set(my_tuple)  # {'a', 'b'}

Замечания:

  1. Преобразование множества удаляет дублирующиеся элементы.

  2. При преобразовании в неиндексированную коллекцию теряется порядок.

  3. Нельзя преобразовать изменяемую коллекцию (например, список) в ключ словаря или элемент множества.

Конспект по части 2/4: Индексирование, срезы, сортировка


Индексирование

Что такое индексирование?

Индексированные коллекции имеют четкий порядок элементов. Каждый элемент коллекции получает номер, начиная с нуля. Это позволяет обращаться к элементу, используя его номер.

Пример:

my_list = ['a', 'b', 'c', 'd']
print(my_list[0])   # 'a' — первый элемент
print(my_list[-1])  # 'd' — последний элемент

Особенности:

  • Положительные индексы считают от начала, начиная с 0.

  • Отрицательные индексы начинают с конца: -1 — последний элемент, -2 — предпоследний и так далее.

Сложные коллекции:

Если коллекция вложенная (например, список списков), можно использовать несколько индексов подряд:

nested_list = [[1, 2], [3, 4]]
print(nested_list[0][1])  # 2 — второй элемент первого списка

Ограничения:

  • В неизменяемых коллекциях (строки и кортежи) можно только читать элементы, но не изменять их.

  • В списках можно менять элементы по индексу:

my_list = [10, 20, 30]
my_list[1] = 50  # Теперь список: [10, 50, 30]

Срезы

Индексы позволяют извлекать отдельные элементы, но что делать, если нужен диапазон? Для этого есть срезы.

Синтаксис среза:

my_list[start:stop:step]
  • start — начальный индекс (включительно).

  • stop — конечный индекс (не включается в результат).

  • step — шаг, с которым извлекаются элементы (по умолчанию 1).

Примеры:

my_list = [10, 20, 30, 40, 50]
print(my_list[1:4])    # [20, 30, 40] — с 1-го по 4-й элемент (4-й не включается)
print(my_list[:3])     # [10, 20, 30] — от начала до 3-го
print(my_list[::2])    # [10, 30, 50] — каждый второй элемент
print(my_list[::-1])   # [50, 40, 30, 20, 10] — в обратном порядке

Важно:

  • Если start или stop выходит за пределы коллекции, ошибки не будет — Python просто возьмет то, что есть.

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

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

my_list = [10, 20, 30, 40, 50]
my_list[1:3] = [25, 35]  # Заменили 20 и 30 на 25 и 35
print(my_list)           # [10, 25, 35, 40, 50]

Сортировка

Сортировка — одна из самых популярных операций с коллекциями. Python предлагает несколько способов сделать это.

Функция sorted()

Эта функция создает новый список с отсортированными элементами, не изменяя оригинальную коллекцию.

Пример:

my_list = [3, 1, 4, 1, 5]
sorted_list = sorted(my_list)
print(sorted_list)  # [1, 1, 3, 4, 5]
print(my_list)      # [3, 1, 4, 1, 5] — исходный список не изменился

Дополнительные параметры:

  • reverse=True — сортировка в обратном порядке.

  • key — позволяет сортировать по определенному критерию:

words = ['apple', 'banana', 'cherry']
sorted_words = sorted(words, key=len)  # Сортировка по длине слов
print(sorted_words)  # ['apple', 'cherry', 'banana']

Метод .sort()

В отличие от sorted(), метод .sort() изменяет сам список.

Пример:

my_list = [3, 1, 4, 1, 5]
my_list.sort()
print(my_list)  # [1, 1, 3, 4, 5]

Обратный порядок

Если требуется вывести элементы в обратном порядке, можно использовать reversed() или срез:

my_list = [10, 20, 30]
reversed_list = list(reversed(my_list))
print(reversed_list)  # [30, 20, 10]

# Альтернатива с использованием среза
print(my_list[::-1])  # [30, 20, 10]

Конспект по части 3/4: Объединение и обновление коллекций, добавление и удаление элементов


Объединение коллекций

Иногда нужно соединить несколько коллекций в одну. Способы объединения зависят от типа коллекции.


Списки, кортежи и строки

  1. Объединение строк и кортежей: Для строк и кортежей используется оператор +, который создает новый объект:

    str1 = 'Hello, '
    str2 = 'world!'
    result = str1 + str2
    print(result)  # 'Hello, world!'
    
    tuple1 = (1, 2, 3)
    tuple2 = (4, 5)
    result = tuple1 + tuple2
    print(result)  # (1, 2, 3, 4, 5)
  2. Объединение списков: У списков больше возможностей:

    • Через оператор +:

      list1 = [1, 2, 3]
      list2 = [4, 5]
      result = list1 + list2
      print(result)  # [1, 2, 3, 4, 5]
    • Через расширенный синтаксис (Python 3.5+):

      list1 = [1, 2, 3]
      list2 = [4, 5]
      result = [*list1, *list2]
      print(result)  # [1, 2, 3, 4, 5]
    • Добавление второго списка как элемента (не объединение):

      list1 = [1, 2, 3]
      list2 = [4, 5]
      result = list1 + [list2]
      print(result)  # [1, 2, 3, [4, 5]]

Словари

Словари объединяются иначе, так как они работают с парами "ключ: значение".

  1. Объединение через методы:

    dict1 = {'a': 1, 'b': 2}
    dict2 = {'c': 3, 'd': 4}
    result = dict1.copy()
    result.update(dict2)
    print(result)  # {'a': 1, 'b': 2, 'c': 3, 'd': 4}
  2. С помощью синтаксиса (Python 3.5+):

    dict1 = {'a': 1, 'b': 2}
    dict2 = {'c': 3, 'd': 4}
    result = {**dict1, **dict2}
    print(result)  # {'a': 1, 'b': 2, 'c': 3, 'd': 4}

Замечание: Если ключи совпадают, значения из второго словаря заменяют значения из первого.


Множества

Множества объединяются с помощью операций над ними:

  1. Объединение (union):

    set1 = {1, 2, 3}
    set2 = {3, 4, 5}
    result = set1.union(set2)
    print(result)  # {1, 2, 3, 4, 5}
    # Альтернативная запись:
    result = set1 | set2
    print(result)  # {1, 2, 3, 4, 5}
  2. Пересечение (intersection):

    result = set1.intersection(set2)
    print(result)  # {3}
    # Альтернативная запись:
    result = set1 & set2
    print(result)  # {3}
  3. Разность (difference):

    result = set1.difference(set2)
    print(result)  # {1, 2}
  4. Симметричная разность (symmetric_difference): Выбираются элементы, которые не пересекаются:

    result = set1.symmetric_difference(set2)
    print(result)  # {1, 2, 4, 5}

Объединение с изменением исходной коллекции

Некоторые методы позволяют изменять существующую коллекцию.

  1. Для списков:

    • Метод .extend() добавляет элементы другой коллекции в конец списка:

      list1 = [1, 2, 3]
      list2 = [4, 5]
      list1.extend(list2)
      print(list1)  # [1, 2, 3, 4, 5]
    • Метод .append() добавляет всю коллекцию как один элемент:

      list1 = [1, 2, 3]
      list2 = [4, 5]
      list1.append(list2)
      print(list1)  # [1, 2, 3, [4, 5]]
  2. Для словарей: Метод .update() добавляет пары ключ: значение из другого словаря:

    dict1 = {'a': 1, 'b': 2}
    dict2 = {'b': 10, 'c': 3}
    dict1.update(dict2)
    print(dict1)  # {'a': 1, 'b': 10, 'c': 3}
  3. Для множеств: Методы с окончанием _update:

    • difference_update(), intersection_update() и другие изменяют множество:

      set1 = {1, 2, 3}
      set2 = {2, 3, 4}
      set1.difference_update(set2)
      print(set1)  # {1}

Добавление и удаление элементов

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


Добавление элементов

  1. Список:

    • append(): добавляет элемент в конец.

    • insert(): вставляет элемент на указанную позицию.

      my_list = [1, 2, 3]
      my_list.append(4)
      print(my_list)  # [1, 2, 3, 4]
      
      my_list.insert(1, 10)  # Вставка на позицию с индексом 1
      print(my_list)  # [1, 10, 2, 3, 4]
  2. Множество:

    • add(): добавляет новый элемент.

      my_set = {1, 2, 3}
      my_set.add(4)
      print(my_set)  # {1, 2, 3, 4}
  3. Словарь:

    • Прямая добавка через ключ:

      my_dict = {'a': 1}
      my_dict['b'] = 2
      print(my_dict)  # {'a': 1, 'b': 2}

Удаление элементов

  1. Список:

    • remove(): удаляет элемент по значению (ошибка, если элемента нет).

    • pop(): удаляет элемент по индексу (по умолчанию — последний).

      my_list = [1, 2, 3]
      my_list.remove(2)
      print(my_list)  # [1, 3]
      
      my_list.pop(0)  # Удалить первый элемент
      print(my_list)  # [3]
  2. Множество:

    • remove() и discard():

      my_set = {1, 2, 3}
      my_set.remove(2)  # Ошибка, если элемента нет
      print(my_set)  # {1, 3}
      
      my_set.discard(4)  # Нет ошибки, даже если элемента нет
  3. Словарь:

    • pop() удаляет элемент по ключу:

      my_dict = {'a': 1, 'b': 2}
      my_dict.pop('a')
      print(my_dict)  # {'b': 2}

Что такое генераторы?

Генераторы — это удобный способ создания коллекций или работы с последовательностями данных. Они позволяют:

  • Сократить код.

  • Создавать элементы «на лету», не занимая много памяти.

  • Применять условия фильтрации и обработки данных.


Типы генераторов

  1. Выражения-генераторы (generator expressions) Позволяют генерировать элементы по одному, без создания полной коллекции.

  2. Генераторы коллекций:

    • Генератор списка (list comprehension): создается в квадратных скобках [].

    • Генератор множества (set comprehension): создается в фигурных скобках {}.

    • Генератор словаря (dictionary comprehension): пары «ключ: значение» указываются в фигурных скобках {key: value}.

Пример:

# Генератор списка
squares = [x**2 for x in range(5)]
print(squares)  # [0, 1, 4, 9, 16]

# Генератор множества
unique_squares = {x**2 for x in range(-4, 4)}
print(unique_squares)  # {0, 1, 4, 9, 16}

# Генератор словаря
dict_squares = {x: x**2 for x in range(5)}
print(dict_squares)  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

Синтаксис генераторов

Генераторы используют цикл for, условия фильтрации (if), а также выражения для обработки элементов.

  1. Базовый синтаксис:

    [выражение for элемент in коллекция if условие]

Пример:

# Квадраты четных чисел
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares)  # [0, 4, 16, 36, 64]
  1. Ветвления (if-else): В генераторах можно использовать условия для обработки элементов.

    [выражение_1 if условие else выражение_2 for элемент in коллекция]

Пример:

# Если число четное — квадрат, иначе — удвоение
result = [x**2 if x % 2 == 0 else x*2 for x in range(5)]
print(result)  # [0, 2, 4, 3, 16]
  1. Вложенные циклы: Генераторы поддерживают вложенные циклы.

    [выражение for элемент_1 in коллекция_1 for элемент_2 in коллекция_2]

Пример:

# Комбинации элементов двух списков
pairs = [(x, y) for x in range(2) for y in range(3)]
print(pairs)  # [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]

Выражения-генераторы

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

Пример:

gen = (x**2 for x in range(5))
print(next(gen))  # 0
print(next(gen))  # 1
print(sum(gen))   # 20 (3^2 + 4^2)

Особенности:

  • Генератор можно использовать только один раз.

  • Для повторного использования нужно создавать его заново.

Важно: Если передать выражение-генератор в функцию, например, sum(), то дополнительные скобки не нужны:

total = sum(x for x in range(5))
print(total)  # 10

Генерация строк

Для строк нельзя использовать выражения-генераторы напрямую. Вместо этого применяют метод .join():

my_list = ['a', 'b', 'c']
result = ''.join(x.upper() for x in my_list)
print(result)  # 'ABC'

Работа с enumerate() и частичный перебор

Использование enumerate()

enumerate() добавляет счетчик к каждому элементу, что полезно при фильтрации или обработке по индексу.

Пример:

names = ['Alice', 'Bob', 'Charlie']
indexed_names = [(i, name) for i, name in enumerate(names)]
print(indexed_names)  # [(0, 'Alice'), (1, 'Bob'), (2, 'Charlie')]

Частичный перебор

Если нужно обработать только первые несколько элементов, используйте itertools.islice():

from itertools import islice

data = range(100)
partial = list(islice(data, 10))  # Первые 10 элементов
print(partial)  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Преимущества генераторов

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

  2. Компактный код: Генераторы позволяют записывать сложную логику обработки данных в одной строке.

  3. Гибкость: Вы можете легко добавлять условия фильтрации и преобразования элементов.

PreviousРегулярные выражения в Python от простого к сложномуNextПараметризованные классы (шаблоны)

Last updated 4 months ago