Практикум по Python: задачи и варианты решений

Раздел: Python -> Задачи по Python

Практические задачи на Python

Как найти максимальное число в списке?

Основное решение: использование встроенной функции max(). Это самый быстрый и читаемый способ.

numbers = [3, 7, 2, 9, 5]
maximum = max(numbers)
print(maximum)  # 9

задачи с кодом python (задачи с кодом на python)

Объяснение: функция max() принимает итерируемый объект и возвращает наибольший элемент. Работает за O(n) и оптимизирована на уровне C.

Как найти максимум без использования встроенной функции?

Вариант с циклом: вручную перебираем элементы, сравнивая с текущим максимумом.

numbers = [3, 7, 2, 9, 5]
maximum = numbers[0]
for num in numbers[1:]:
    if num > maximum:
        maximum = num
print(maximum)  # 9

Python практические задачи (практические задачи на python)

Объяснение: инициализируем первым элементом, затем проходим по остальным. Подходит для обучения и понимания логики.

Как найти максимум с помощью reduce?

Вариант с functools.reduce: функциональный подход.

from functools import reduce
numbers = [3, 7, 2, 9, 5]
maximum = reduce(lambda a, b: a if a > b else b, numbers)
print(maximum)  # 9

Объяснение: reduce последовательно применяет лямбду к элементам, сохраняя текущий максимум. Менее читаемо, но демонстрирует функциональный стиль.

Типичные ошибки:

  • Пустой список: max([]) вызовет ValueError. Решение: проверять список или указывать аргумент default: max(numbers, default=None).
  • Разные типы данных: если в списке смешаны числа и строки, max() вызовет TypeError. Нужно убедиться в однородности.
  • При реализации вручную забыть учесть все элементы (например, начать с 0 вместо первого элемента при отрицательных числах).

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

Основное решение: использование dict.fromkeys() (Python 3.7+ гарантирует порядок) или OrderedDict для старых версий.

items = [1, 2, 1, 3, 2, 4]
unique = list(dict.fromkeys(items))
print(unique)  # [1, 2, 3, 4]

Объяснение: dict.fromkeys() создает словарь, где ключи уникальны и сохраняют порядок появления. Преобразование обратно в список дает уникальные элементы.

Как удалить дубликаты с помощью множества?

Вариант с set: быстро, но не сохраняет порядок.

items = [1, 2, 1, 3, 2, 4]
unique = list(set(items))
print(unique)  # [1, 2, 3, 4] (порядок может быть любым)

Объяснение: set удаляет дубликаты, но теряет исходный порядок. Подходит, если порядок не важен.

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

Вариант с циклом и списком:

items = [1, 2, 1, 3, 2, 4]
unique = []
for item in items:
    if item not in unique:
        unique.append(item)
print(unique)  # [1, 2, 3, 4]

Объяснение: проходим по исходному списку и добавляем элемент только если его еще нет. Сложность O(n^2) из-за проверки in для списка, но наглядно.

Типичные ошибки:

  • Порядок не сохраняется при использовании простого set().
  • Сравнение элементов с разными типами: 1 == '1' выдаст False, дубликат не удалится.
  • Использование list(set(items)) для большого списка – быстро, но недетерминированный порядок может быть проблемой.

Как проверить, является ли строка палиндромом?

Основное решение: сравнение строки с обратной версией с помощью среза.

s = "racecar"
if s == s[::-1]:
    print("Палиндром")
else:
    print("Не палиндром")

Объяснение: срез s[::-1] возвращает строку задом наперед. Сравнение производится быстро.

Как проверить палиндром с игнорированием регистра и пробелов?

Вариант с очисткой строки:

s = "A man, a plan, a canal: Panama"
clean = ''.join(c.lower() for c in s if c.isalnum())
if clean == clean[::-1]:
    print("Палиндром")
else:
    print("Не палиндром")

Объяснение: удаляем все не буквенно-цифровые символы и приводим к нижнему регистру. Затем проверяем обычным способом.

Как проверить палиндром с помощью двух указателей?

Вариант без дополнительной памяти:

def is_palindrome(s):
    left, right = 0, len(s) - 1
    while left < right:
        while left < right and not s[left].isalnum():
            left += 1
        while left < right and not s[right].isalnum():
            right -= 1
        if s[left].lower() != s[right].lower():
            return False
        left += 1
        right -= 1
    return True

print(is_palindrome("A man, a plan, a canal: Panama"))  # True

Объяснение: два указателя двигаются навстречу, пропуская не буквенно-цифровые символы. Эффективно по памяти – O(1).

Типичные ошибки:

  • Учет регистра: "Racecar" и "racecar" при прямом сравнении не будут равны.
  • Игнорирование знаков препинания: "race car" не является палиндромом из-за пробела, если не очистить.
  • Пустая строка: считается палиндромом (длина 0).
  • Одиночные символы – всегда палиндромы.

Как подсчитать количество строк в текстовом файле?

Основное решение: использование enumerate или просто sum() с генератором.

with open('file.txt', 'r', encoding='utf-8') as f:
    line_count = sum(1 for _ in f)
print(f"Строк: {line_count}")

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

Как подсчитать строки, не считая пустые?

Вариант с фильтрацией:

with open('file.txt', 'r', encoding='utf-8') as f:
    non_empty = sum(1 for line in f if line.strip())
print(f"Непустых строк: {non_empty}")

Объяснение: line.strip() удаляет пробельные символы, пустая строка после strip даст False.

Как подсчитать строки с помощью readlines?

Вариант для небольших файлов:

with open('file.txt', 'r', encoding='utf-8') as f:
    lines = f.readlines()
    line_count = len(lines)
print(f"Строк: {line_count}")

Объяснение: readlines() считывает все строки в список. Просто, но не подходит для очень больших файлов из-за потребления памяти.

Типичные ошибки:

  • Не указана кодировка: может привести к UnicodeDecodeError при наличии специфичных символов. Всегда используйте encoding='utf-8'.
  • Путь к файлу не существует: возникает FileNotFoundError. Нужно проверять или использовать блок try/except.
  • Символ конца строки (newline) считается частью строки, поэтому метод len(readlines()) корректно считает строки.

Расширенные примеры

1. Поиск индексов всех максимальных значений

Если в списке несколько одинаковых максимумов, нужно найти их индексы.

Пример
def indices_of_max(lst):
    max_val = max(lst) if lst else None
    if max_val is None:
        return []
    return [i for i, v in enumerate(lst) if v == max_val]

numbers = [1, 5, 3, 5, 2]
print(indices_of_max(numbers))  # [1, 3]
[1, 3]

2. Поиск n наибольших элементов с помощью heapq

Используем heapq.nlargest для получения нескольких максимумов.

Пример
import heapq
numbers = [10, 3, 7, 15, 9, 20]
top3 = heapq.nlargest(3, numbers)
print(top3)  # [20, 15, 10]
[20, 15, 10]

Объяснение: heapq работает за O(n log k), где k – количество искомых элементов. Эффективно для больших списков.

3. Удаление дубликатов с сохранением порядка и подсчетом количества

Используем collections.Counter для подсчета повторений.

Пример
from collections import Counter
items = [1, 2, 1, 3, 2, 4]
unique_order = list(dict.fromkeys(items))
counts = Counter(items)
print("Уникальные:", unique_order)
print("Количество:", dict(counts))
Уникальные: [1, 2, 3, 4]
Количество: {1: 2, 2: 2, 3: 1, 4: 1}

4. Проверка палиндрома для произвольной последовательности (рекурсия)

Пример
def is_palindrome_recursive(s):
    if len(s) <= 1:
        return True
    if s[0] != s[-1]:
        return False
    return is_palindrome_recursive(s[1:-1])

print(is_palindrome_recursive("racecar"))  # True
print(is_palindrome_recursive("hello"))    # False
True
False

5. Чтение файла с построчной обработкой и фильтрацией по длине

Пример
with open('sample.txt', 'r', encoding='utf-8') as f:
    long_lines = [line.rstrip() for line in f if len(line) > 50]
print(f"Найдено строк длиннее 50 символов: {len(long_lines)}")
# Вывод первых трех
for line in long_lines[:3]:
    print(line)
Найдено строк длиннее 50 символов: 2
Это очень длинная строка, содержащая более пятидесяти символов для демонстрации.
Еще одна строка, которая явно превышает лимит в 50 символов, добавленная для примера.

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

Пример
import mmap
with open('large_file.txt', 'r') as f:
    with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mm:
        # разбиваем по символу новой строки
        count = mm.count(b'\n')
print(f"Строк: {count}")

Объяснение: mmap отображает файл в память, подсчет newlines происходит на уровне операционной системы, эффективно для гигабайтных файлов.

7. Группировка дубликатов с сохранением индексов

Пример
items = [1, 2, 1, 3, 2, 4]
from collections import defaultdict
groups = defaultdict(list)
for i, v in enumerate(items):
    groups[v].append(i)
print(dict(groups))
# {1: [0, 2], 2: [1, 4], 3: [3], 4: [5]}
{1: [0, 2], 2: [1, 4], 3: [3], 4: [5]}

8. Быстрая проверка палиндрома для чисел (без преобразования в строку)

Пример
def is_palindrome_number(x):
    if x < 0 or (x % 10 == 0 and x != 0):
        return False
    reversed_half = 0
    while x > reversed_half:
        reversed_half = reversed_half * 10 + x % 10
        x //= 10
    return x == reversed_half or x == reversed_half // 10

print(is_palindrome_number(121))   # True
print(is_palindrome_number(12321)) # True
print(is_palindrome_number(10))    # False
True
True
False

Объяснение: переворачиваем вторую половину числа и сравниваем с первой. Экономит память и подходит для больших чисел.

9. Чтение файла с пропуском заголовка и подсчетом статистики

Пример
with open('data.csv', 'r', encoding='utf-8') as f:
    next(f)  # пропустить заголовок
    total = 0
    count = 0
    for line in f:
        if line.strip():
            parts = line.split(',')
            try:
                value = float(parts[1])
                total += value
                count += 1
            except (IndexError, ValueError):
                continue
    avg = total / count if count else 0
print(f"Среднее значение второго столбца: {avg:.2f}")

10. Использование itertools.groupby для группировки последовательных дубликатов

Пример
from itertools import groupby
items = [1, 1, 2, 2, 2, 3, 1, 1]
grouped = [(k, list(g)) for k, g in groupby(items)]
print(grouped)
# [(1, [1, 1]), (2, [2, 2, 2]), (3, [3]), (1, [1, 1])]
[(1, [1, 1]), (2, [2, 2, 2]), (3, [3]), (1, [1, 1])]

Объяснение: groupby группирует только последовательные одинаковые элементы, в отличие от общего удаления дубликатов.

Практические задачи на Python - comments

En
Python практические задачи (python)