Найти тему

Программирование на Python. Основы работы с массивами данных

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

Мы начнем рассмотрение сразу с двух типов массивов. В Python их четыре, но начнем с двух самых простых. К слову, в некоторых языках программирования (особенно старых) есть всего один тип массива, самый простой. Вот с самого простого и начнем. Благо во всех языках принцип их работы одинаковый.

С одним из типов простых массивов вы уже познакомились в прошлом уроке. Просто вы не знали, что это массив. Да, мы говорим о строках. Набор символов (а именно это и есть строка) является массивом этих самых символов. Именно поэтому для того, чтобы обратиться к какому-то конкретному символу строки по его индексу, нужно было воспользоваться такой записью:

s[i],

где s – это, собственно, переменная, содержащая строку, а i – числовой индекс нужного нам символа (напомним, что индексы начинаются с нуля).

Работа с элементами массива (т.е. содержащимися в массиве данными) осуществляется точно таким же образом – обращение по их индексу; начало тоже с нуля.

Что же такое массив и для чего он нужен? Давайте представим, что есть десять фамилий, которые нужно сначала ввести в программу, с ними что-то сделать, а потом вывести. Когда будем их вводить, то куда они будут сохраняться? В разные переменные? Ну, хорошо, пусть в переменные. Потребуется 10 переменных. Это нетрудно организовать. А если будет не 10, а 100 фамилий? А 1000? Устанем переменные придумывать.

А потом еще нужно с данными работать. Как будем перебирать данные, чтобы что-то сделать с ними? Каждую переменную будем брать отдельно? Цикл-то не получится использовать. А вот если мы все данные сохраним в какой-то массив, то уже можно будет организовать цикл для перебора фамилий, т.к. у каждой фамилии будет свой индекс.

Массив – это набор элементов, оформленный как объект, доступный для просмотра и редактирования.

Помните, когда мы проходили цикл for, мы говорили, что для его инициализации (для запуска) необходима функция range(), которая создает набор чисел арифметической прогрессии. Так вот, вопрос: является ли этот набор чисел массивом? Ведь числа мы можем перебирать, как в массиве. Ответ – нет, не является, и вот почему.

В современных языках программирования есть такое понятие, как итерируемый объект. Это набор значений (не обязательно чисел), которые можно перебирать. Массивы – тоже итерируемые объекты, но они доступны для редактирования, и их содержимое можно просматривать. Содержимое массивов выводится на экран с помощью функции print() без всяких «костылей» (хитростей). А вот просто итерируемые объекты, которые не оформлены как массив, на экран просто так не выведешь и не отредактируешь. Для понимания, о чем мы говорим, попробуйте самостоятельно вывести через print() функцию range() с какими-нибудь значениями – ведь результатом, по логике, должен быть набор чисел. Посмотрите, что получится.

Итак, начнем с простого. Как создать массив? Все просто. Есть два варианта:

arr = [] (это квадратные скобки, если что)

arr = list()

Квадратные скобки и функция list() производят одно и то же действие – создают массив arr (это просто название переменной).

Конкретно в приведенном случае создается пустой массив, готовый, как говорится, к наполнению разными элементами. Но можно создавать массивы сразу с содержанием элементов, например, наша задача с фамилиями:

fams = [‘Иванов’, ‘Петров’, ‘Сидоров’, ‘Попов’, ‘Кузнецов’]

Давайте выведем на экран значение переменной fams, чтобы понять, как Python это делает:

Видите, выводится в форматированном виде, т.е. с квадратными скобками. Квадратные скобки – это признак данного типа массива. Этот тип массива в Питоне называется список. Запомните это.

В списках с его элементами можно делать все, что угодно: удалять, изменять, добавлять. Например, давайте добавим в список еще одну фамилию. Это делается с помощью метода .append():

fams.append(‘Соколов’)

Новый элемент списка будет расположен в конце массива.

Если мы хотим добавить не в конец, а вставить в самое начало или между какими-то конкретными элементами, то для этого используется метод .insert(i, x), где i – это позиция в списке, а х – новый элемент. Например, чтобы поместить новую фамилию на третью позицию, необходимо написать так:

fams.insert(2, ‘Морозов’)

Для того чтобы удалить какой-либо элемент из списка, чаще всего используется метод .pop(). Если в скобках указать индекс элемента, то удалится именно этот элемент, если оставить скобки пустыми, то удалится последний элемент списка. Например, чтобы нам удалить этого «Морозова», необходимо написать так:

fams.pop(2)

Кроме того, данный метод позволяет параллельно с удалением элемента сохранить его значение в какой-нибудь переменной, ну, или вывести его на экран. Иногда это бывает крайне полезно. В общем, если мы хотим сохранить удаляемого «Морозова», то придется переписать эту строку кода таким образом:

a = fams.pop(2)

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

arr = (‘Вася’, ‘Федя’, ‘Петя’)

arr = tuple()

Для чего они нужны? Хороший вопрос. Возможно, для того, чтобы их никто не мог изменить специально или ненароком. Повторимся, что ни добавить новый элемент, ни изменить существующий, ни удалить какой-то элемент – невозможно. Можно сказать, что это массив-константа.

Возвращаемся к спискам. Именно с ними чаще всего работают. По крайней мере, начинающие программисты. Да и вообще, списки повсеместно используются.

Как изменить какой-то конкретный элемент списка? Обратиться к нему по его индексу. К примеру, чтобы изменить мужскую фамилию Попов на женскую Попова, мы можем сделать так:

fams[3] = ‘Попова’

Или так:

fams[3] = fams[3] + ‘а’

Как видите, с элементами массивов мы работаем так же, как и с обычными переменными.

Самый короткий вариант выглядит так:

fams[3] += ‘а’

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

  • a = a + 1,
  • a = a * 2,
  • a = a – 10
  • a = a / 3

придумали сокращенную запись, соответственно:

  • a += 1,
  • a *= 2,
  • a -= 10
  • a /= 3

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

Кстати, почему мы обратились к третьему элементу списка fams[3], ведь Попов – это четвертый по счету элемент массива? Все верно, четвертый. Но, напомним, индексация в массивах начинается с нуля. Поэтому, если Иванов имеет индекс 0, то Попов – как раз 3.

Теперь давайте применим наши навыки работы с циклами и автоматизируем превращение элементов нашего списка в женские фамилии путем добавления в конце каждой фамилии буквы «а»:

-2

Смотрите, в функции range() мы не указали начальное значение числового ряда. По умолчанию это ноль. А цифра 6, как мы уже говорили, не войдет в числовой ряд. Получается, range(6) создаст набор цифр от нуля до пяти – как раз все индексы нашего списка. Но если, к примеру, нам не известна длина списка, выручит функция len() – помните, в прошлом уроке мы ее использовали для определения длины строки? Вот таким же образом она применяется и для определения длины массивов. Тогда мы бы записали так:

for i in range(len(fams)):

Кстати, элементы массива можно перебирать и следующим образом:

for f in fams:

В данном случае в переменной f сохраняются последовательно значения элементов списка fams. Почему же мы не использовали сразу эту запись? Ведь она значительно короче, к тому же нет необходимости знать длину массива. Все верно, если не одно НО. В данном случае нельзя будет сохранить новые значения элементов. То есть, получается, данная конструкция подходит только для перебора элементов с целью, например, использования их значения для чего-то другого, например, для простого вывода на экран или для работы с другими переменными или массивами.

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

arr = [‘Три’, False, fams, func(), 2]

Эта запись не выдаст ошибку. И да, в массив можно поместить массив (fams).

Хоть в массив одновременно можно «запихать» разные типы данных, работать с ними будет неудобно или затруднительно. Желательно, конечно, задавать для каждого типа отдельный массив. Но, как говорится, хозяин – барин. Если вы посчитаете, что вам удобнее все вместе – делайте.

Теперь о том, как использовать функцию list(). В скобках должен находиться итерируемый объект, который эта функция преобразует в список. Например, для ввода сразу нескольких данных с помещением их в массив, обычно используется такая конструкция:

arr = list(input(‘Введите данные через пробел: ’).split())

Давайте ее разберем.

После ввода через функцию input() данные разделяются методом .split() по пробелам, образуя собой некий набор. Далее этот набор данных формируется функцией list() в список, с которым уже можно работать: вывести, изменить и т.д.

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

print(*arr)

Поэкспериментируйте сами, каким будет результат.

Комменты приветствуются, за палец вверх - отдельное спасибо. Удачи!

Задания

Для формирования исходных списков использовать метод random.randint(1, 100) модуля random.Для наглядности список выводить на экран. Если не указан размер исходного списка, принимать его равным 10.

1. Дано целое число N. Сформировать и вывести целочисленный список, содержащий N первых положительных нечетных чисел: 1, 3, 5, …

2. Дано целое число N. Сформировать и вывести целочисленный список, содержащий числа, являющиеся степенями цифры 2, от 1-й до N-ой степени.

3. Дано целое число N. Сформировать и вывести список, состоящий из N первых чисел Фибоначчи.

4. Даны целые числа N (>2), А и В. Сформировать и вывести список размера N, в котором первый элемент равен числу А, второй – числу В, а последующие – сумме всех предыдущих.

5. Дан список размера N. Сформировать и вывести новый список из данного, в котором элементы будут расположены в обратном порядке.

6. Дан целочисленный список размера N. Сформировать из него и вывести два списка. Элементами первого будут нечетные числа, элементами второго – четные.

7. Дан целочисленный список размера N и число К (K<N). Сформировать новый список, элементами которого будут элементы исходного списка с индексами, кратными числу К. Условный оператор не использовать.

8. Дан список из 10 ненулевых целых чисел. Вывести значение первого элемента, который соответствует условию Ai < A10. Если таких элементов нет, то вывести 0.

9. Дан целочисленный список. Вывести порядковый номер последнего из тех его элементов Ai, которые удовлетворяют двойному неравенству A1 < Ai < A10. Если таких элементов нет, то вывести 0.

10. Дан список размера N и числа К1 и К2 (1 ≤ K1 ≤ K2 < N). Найти сумму элементов от К1 до К2 включительно.

11. То же самое, но найти сумму всех элементов, кроме тех, что находятся в диапазоне от К1 до К2 включительно.

12. Дан целочисленный список, не содержащий одинаковых чисел. Проверить, образуют ли его элементы арифметическую прогрессию. Если да, то вывести разность прогрессии, если нет, то – 0.

13. Дан целочисленный список. Проверить, чередуются ли в нем четные и нечетные числа. Если чередуются, то вывести 0, иначе – вывести номер первого элемента, нарушающего закономерность.

14. Дан список. Найти минимальный элемент из его элементов с четными номерами. Вывести его значение и индекс.

15. Дан список. Сформировать новый список из элементов старого, которые больше своего правого соседа.

16. Дан список. Вывести номер и значение элемента, который является первым локальным минимумом (меньше своих соседей).

17. Дан список. Вывести номер и значение элемента, который является последним локальным максимумом (больше своих соседей).

18. Дан список. Найти максимальный из его локальных минимумов. Для наглядности сформировать и вывести список локальных минимумов.

19. Даны список и число R. Найти элемент списка, который по значению наиболее близок к числу R.

20. Дан целочисленный список с элементами, принимающими значение от 1 до 10. Найти количество различных элементов в списке.

21. Даны два списка одинакового размера. Сформировать и вывести новый список, элементами которого будут являться все элементы из двух данных, в порядке очередности: первым элементом будет первый элемент из первого списка, вторым – первый элемент из второго списка, третьим – второй элемент из первого и т.д.

22. Даны два списка одинакового размера. Сформировать и вывести новый список, в котором каждый из элементов будет являться максимумом из двух элементов того же индекса из заданных списков.

23. Дан список. Сформировать и вывести два новых списка. В первом собрать все нечетные числа, а во втором – все четные числа из исходного списка.

24. Дан список. Сформировать и вывести новый список, элементы которого соответствуют следующему правилу: элемент с текущим индексом равен сумме всех элементов исходного списка с индексами с нулевого до текущего.

25. То же самое, но элемент с текущим индексом равен не сумме, а среднему арифметическому.

26. Дан список размера N и целое число К (1 ≤ К ≤ N). Преобразовать список, увеличив каждый его элемент на исходное значение элемента АК.

27. Дан целочисленный список. Увеличить все четные числа на исходное значение первого четного числа и уменьшить все нечетные числа на исходное значение последнего нечетного числа. Если четных или нечетных чисел в исходном списке нет, то оставить соответствующие числа без изменений.

28. Дан список. Поменять местами его минимальный и максимальный элементы.

29. Дан список. Поменять местами первый элемент со вторым, третий с четвертым и т.д.

30. Дан список. Поменять местами его первую и вторую половины.

31. Дан список и целые числа А и В, лежащие в диапазоне 0..9. Переставить в обратном порядке элементы массива, расположенные между элементами с индексами А и В.

32. Дан список. Обнулить все его локальные максимумы.

33. Дан список размера N и целое число К (1 ≤ К ≤ N). Осуществить сдвиг элементов списка вправо на К позиций (А1 перейдет на позицию АК+1, А2 – на позицию АК+2 и т.д.). Исходное значение последних К элементов списка будет потеряно, первые К элементы списка обнулить.

34. Дан список. Осуществить циклический сдвиг влево на одну позицию. При этом первый элемент станет последним.

35. Дан список размера N и целое число К (1 ≤ К ≤ N). Осуществить циклический сдвиг элементов списка вправо на К позиций.

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

37. Дан список, в котором все элементы, кроме последнего упорядочены по убыванию. Упорядочить список полностью.

38. Дан список и целые числа А и В. Удалить из списка элементы с номерами от А до В включительно. Вспомогательные списки не создавать.

39. Дан целочисленный список. Удалить из него все нечетные элементы. Вспомогательные списки не создавать.

40. Дан целочисленный список и число К, принимающее значение 0 или 1. Если К равно 0, удалить из списка элементы с четными номерами, если 1 – нечетными. Условный оператор не использовать. Вспомогательные списки не создавать.

41. Дан список из 30 элементов; значение каждого элемента может принимать значение от 1 до 10. Удалить все повторяющиеся элементы, оставив их первые вхождения. Вспомогательные списки не создавать.

42. Дан список из 30 элементов; значение каждого элемента может принимать значение от 1 до 10. Удалить все элементы, встречающиеся менее трех раз. Вспомогательные списки не создавать.

43. Дан список и число N (0<N<9). Вставить нулевые элементы непосредственно до и после элемента с номером N.

44. Дан список. Продублировать элементы с четными номерами и утроить количество элементов с нечетными значениями.

45. Дан список. Упорядочить в нем элементы по возрастанию, используя «пузырьковый» метод (сортировка простым обменом). Суть метода: просматривать список по-парно (сравнивать первый элемент со вторым, второй с третьим и т.д.) для нахождения большего элемента в паре, менять элементы местами, если нужно, повторить действия со списком N-1 раз (N – размер списка). Для лучшего понимания работы алгоритма, выводить на экран все промежуточные результаты после каждого просмотра всего списка. Учесть, что после каждого просмотра количество анализируемых пар можно сократить на 1.

46. Дан список. Упорядочить в нем элементы по возрастанию методом сортировки «простым выбором». Суть метода: Найти максимальный элемент списка и поменять его местами с последним элементом. Выполнить это действие N-1 раз (N – размер списка), каждый раз уменьшая на 1 количество анализируемых элементов и выводя промежуточный результат.