📖 Теория: строки, списки и циклы

⚡ Кратко

Урок — практикум, поэтому теория дана кратко: методы строк, операции со списками и циклы.

  • Строки неизменяемы, списки — изменяемы.
  • Регистр: upper(), lower(), title(), capitalize(), swapcase().
  • Поиск: find() возвращает -1, index() вызывает ValueError.
  • Разделение и склейка: split() и join().
  • Списки: создание [], индексация [0], срезы [1:4], изменение lst[i] = x.
  • Цикл for по коллекции; range(start, stop, step) — для индексов.
text = "Python"
print(text.lower())  # python
print(text)          # Python — исходная строка не изменилась

numbers = [1, 2, 3]
numbers[0] = 10
print(numbers)       # [10, 2, 3]

Неизменяемость строк vs изменяемость списков

В Python строки относятся к неизменяемым (immutable) типам, а списки — к изменяемым (mutable). Это влияет на то, как мы работаем с методами и операторами.

📄 examples/string_vs_list.py
text = "hello"
# text[0] = "H"  # TypeError: 'str' object does not support item assignment
new_text = text.capitalize()
print(text)      # hello
print(new_text)  # Hello

numbers = ["h", "e", "l", "l", "o"]
numbers[0] = "H"
print(numbers)   # ['H', 'e', 'l', 'l', 'o']

Группы методов строк

1. Изменение регистра

📄 examples/case_methods.py
text = "Hello, worlD!"
print(text.upper())       # HELLO, WORLD!
print(text.lower())       # hello, world!
print(text.capitalize())  # Hello, world!
print(text.title())       # Hello, World!
print(text.swapcase())    # hELLO, WORLd!

find() безопасен: при отсутствии подстроки возвращает -1. index() вызывает ValueError.

📄 examples/find_index.py
text = "Python is awesome. Python is dynamic."
print(text.find("Python"))   # 0
print(text.rfind("Python"))  # 19
print(text.find("Java"))     # -1
print(text.count("Python"))  # 2

3. Замена подстрок

📄 examples/replace.py
text = "I love Python, Python is great"
print(text.replace("Python", "Java"))
# I love Java, Java is great

fruits = "apple apple apple"
print(fruits.replace("apple", "orange", 1))
# orange apple apple

4. Разделение и объединение

split() без аргументов разделяет по любым пробельным символам и убирает пустые фрагменты. split(" ") разделяет только по одному пробелу.

📄 examples/split_join.py
text = "apple     banana\t cherry\n"
print(text.split())      # ['apple', 'banana', 'cherry']
print(text.split(" "))   # ['apple', '', '', '', '', 'banana\t', 'cherry\n']

words = ["Python", "is", "awesome"]
print(" ".join(words))   # Python is awesome

5. Удаление символов с краёв

📄 examples/strip.py
text = "\t  hello world\n  "
print(text.strip())        # hello world
print("***hello***".strip("*"))   # hello
print("**--*hello---***".strip("*-"))  # hello

6. Предикатные методы

📄 examples/predicates.py
print("Hello".isalpha())            # True
print("Python3".isalpha())          # False
print("12345".isdigit())            # True
print("12345.1".isdigit())          # False
print("Hello World".istitle())      # True
print("Hello World".startswith("Hello"))  # True
print("Hello World!".endswith("ld!"))     # True

Списки

Создание и индексация

📄 examples/lists.py
fruits = ["apple", "banana", "cherry"]
print(fruits[0])     # apple
print(fruits[-1])    # cherry
print(fruits[1:3])   # ['banana', 'cherry']

Изменение по индексу и срезу

📄 examples/list_mutation.py
numbers = [1, 2, 3, 4, 5]
numbers[0] = 10
numbers[1:3] = [20, 30]
print(numbers)  # [10, 20, 30, 4, 5]

Цикл for со списками

📄 examples/list_loop.py
numbers = [1, 2, 3, 4, 5]
for number in numbers:
    print(number ** 2)

Работа с индексами через range()

Функция range(stop) генерирует числа от 0 до stop-1. Полная форма: range(start, stop, step).

📄 examples/range_demo.py
numbers = [10, 20, 30, 40, 50]
for i in range(len(numbers)):
    print(f"Индекс {i}: {numbers[i]}")

for i in range(0, len(numbers) - 1, 2):
    print(f"Пара ({numbers[i]}, {numbers[i + 1]})")
Проверить по документации: функции enumerate() и zip() выходят за рамки исходного занятия, но удобны для работы с индексами и парами списков.

Современные практики

Для форматирования удобнее использовать f-strings, а для преобразования коллекций — list comprehensions и генераторные выражения. Guard clause — это проверка на «плохой» случай в начале блока, которая позволяет уменьшить вложенность.

📄 examples/modern_practices.py
name = "Python"
version = 3
print(f"Язык: {name}, версия: {version}")

numbers = [1, 2, 3, 4, 5]
squares = [n ** 2 for n in numbers]
print(squares)

# Guard clause
def is_valid_name(text):
    if not text:
        return False
    return text[0].isupper() and text.isalpha()

print(is_valid_name("Alice"))  # True
print(is_valid_name("bob"))    # False
Проверить по документации: f-strings, list comprehensions, генераторные выражения и guard clauses выходят за рамки исходного занятия. Они описаны в официальной документации Python и в материалах Real Python (см. Ресурсы).