[ Сборник задач ] Тема 6. Работа с кортежами

Кортеж (tuple) – неизменяемый тип данных. Эта последовательность является упорядоченной и итерируемой, к элементам можно получить доступ по индексу.

Чаще всего кортежи используются для разнородных данных (представленных строками, числами, списками, множествами и т.п.).

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

Углубиться в тему можно при помощи namedtuple из модуля collections, которые позволяют давать имена каждому элементу последовательности, делая эту структуру данных в чем-то похожей на словарь.

Задача 1. Базовый уровень

Условие

Напишите функцию tpl_sort(), которая сортирует кортеж, состоящий из целых чисел по возрастанию и возвращает его. Если хотя бы один элемент не является целым числом, то функция возвращает исходный кортеж. 

Встроенная функция sorted() по-умолчанию возвращает список элементов, отсортированных по возрастанию значений. Остается только проверить, чтобы каждый элемент являлся числом, а конечный список преобразовать в кортеж.
Решение – IDE

def tpl_sort(tpl):
    for element in tpl:
        if not isinstance(element, int):
            return tpl
    return tuple(sorted(tpl))

# Тесты
print(tpl_sort((5, 5, 3, 1, 9)))
print(tpl_sort((5, 5, 2.1, '1', 9)))


Результат выполнения

(1, 3, 5, 5, 9)
(5, 5, 2.1, '1', 9)

Задача 2. Базовый уровень

Условие

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

Чтобы решить задачу, требуется вспомнить про срезы.
Решение 1 Решение — IDE

def slicer(any_tuple, element):
    if element in any_tuple:
        if any_tuple.count(element) > 1:
            first_index = any_tuple.index(element)
            second_index = any_tuple.index(element, first_index + 1) + 1
            return any_tuple[first_index:second_index]
        else:
            return any_tuple[any_tuple.index(element):]
    else:
        return ()

Решение 2Решение — IDE

BEGIN_INDEX = 0
END_INDEX = -1

def slicer(any_tuple, element):
    first = second = BEGIN_INDEX
    
    if element in any_tuple:
        first = any_tuple.index(element)
    if any_tuple.count(element) > 1:
        second = any_tuple.index(element, first + 1) + 1
    else:
        second = END_INDEX

    return any_tuple[first:second]

# Тесты
print(slicer((1, 2, 3), 8))
print(slicer((1, 8, 3, 4, 8, 8, 9, 2), 8))
print(slicer((1, 2, 8, 5, 1, 2, 9), 8))



Результат выполнения

()
(8, 3, 4, 8)
(8, 5, 1, 2, 9)

Задача 3. Базовый уровень

Условие

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

Обойти систему, к сожалению, у Николая не получится. Однако он может при помощи срезов создать новые кортежи и их склеить для получения необходимого результата.
Решение 1Решение — IDE

def del_from_tuple(tpl, elem):
    if elem in tpl:
        elem_index = tpl.index(elem)
        return tpl[:elem_index] + tpl[elem_index + 1:]
    return tpl

# Тесты 
print(del_from_tuple((1, 2, 3), 1))
print(del_from_tuple((1, 2, 3, 1, 2, 3, 4, 5, 2, 3, 4, 2, 4, 2), 3))
print(del_from_tuple((2, 4, 6, 6, 4, 2), 9))

Решение 2Решение — IDE

def del_from_tuple(tpl, elem):
    lst = list(tpl)
    if elem in tpl:
        lst.remove(elem)
    return tuple(lst)
# Тесты 
print(del_from_tuple((1, 2, 3), 1))
print(del_from_tuple((1, 2, 3, 1, 2, 3, 4, 5, 2, 3, 4, 2, 4, 2), 3))
print(del_from_tuple((2, 4, 6, 6, 4, 2), 9))

Результат выполнения

(2, 3)
(1, 2, 1, 2, 3, 4, 5, 2, 3, 4, 2, 4, 2)
(2, 4, 6, 6, 4, 2)

Задача 4. Продвинутый уровень

Условие

Создайте кортеж из 7-ми именованных кортежей учащихся ВУЗов. В именованном кортеже будут присутствовать следующие поля: имя студента, возраст, оценка за семестр, город проживания. Функция good_students() будет принимать этот кортеж, вычислять среднюю оценку по всем учащимся и выводить на печать следующее сообщение: “Ученики {список имен студентов через запятую} в этом семестре хорошо учатся!”. В список студентов, которые выводятся по результатам работы функции, попадут лишь те, у которых оценка за семестр равна или выше средней по всем учащимся.

Сначала требуется создать объект namedtuple с 4-мя обозначенными полями. Потом придумать 7 случайных студентов, которые заносятся в кортеж.
Далее определяем среднюю отметку за семестр и формируем список учащихся, у которых оценка выше средней.
Решение — IDE

from collections import namedtuple
Student = namedtuple('Student', 'name age mark city')
students = (
   Student('Елена', '13', 7.1, 'Москва'),
   Student('Ольга', '11', 7.9, 'Иваново'),
   Student('Елизавета', '14', 9.1, 'Тверь'),
   Student('Дмитрий', '12', 5.2, 'Челябинск'),
   Student('Максим', '15', 6.1, 'Самара'),
   Student('Николай', '11', 8.7, 'Владивосток'),
   Student('Артур', '13', 5.8, 'Екатеринбург')
)


def good_students(students):
   total_mark = 0

   for student in students:
       total_mark += student.mark
   avg_mark = total_mark / len(students)

   good_mark_students = [student.name for student in students if student.mark >= avg_mark]
   print('Ученики ', ', '.join(good_mark_students), ' в этом семестре хорошо учатся!')

good_students(students)

Результат выполнения

Ученики Ольга, Елизавета, Николай в этом семестре хорошо учатся!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *