Цикл for
Цикл for в языке программирования Python предназначен для перебора элементов структур данных и других составных объектов. Это не цикл со счетчиком, каковым является for во многих других языках.
Что значит перебор элементов? Например, у нас есть список, состоящий из ряда элементов. Сначала берем из него первый элемент, затем второй, потом третий и так далее. С каждым элементом мы выполняем одни и те же действия в теле for . Нам не надо извлекать элементы по их индексам, заботиться, на каком из них список заканчивается, и следующая итерация бессмысленна. Цикл for сам переберет и определит конец.
>>> spisok = [10, 40, 20, 30] >>> for element in spisok: . print(element + 2) . 12 42 22 32
После ключевого слова for используется переменная под именем element . Имя здесь может быть любым. Нередко используют i . На каждой итерации цикла for ей будет присвоен очередной элемент из списка spisok . Так при первой прокрутке цикла идентификатор element связан с числом 10, на второй – с числом 40, и так далее. Когда элементы в spisok заканчиваются, цикл for завершает свою работу.
С английского «for» переводится как «для», «in» как «в». Перевести конструкцию с языка программирования на человеческий можно так: для каждого элемента в списке делать следующее (то, что в теле цикла).
В примере мы увеличивали каждый элемент на 2 и выводили его на экран. При этом сам список конечно же не изменялся:
>>> spisok [10, 40, 20, 30]
Нигде не шла речь о перезаписи его элементов, они просто извлекались и использовались. Однако бывает необходимо изменить сам список, например, изменить значение каждого элемента в нем или только определенных, удовлетворяющих определенному условию. И тут без переменной, обозначающей индекс элемента, случаев не обойтись:
>>> i = 0 >>> for element in spisok: . spisok[i] = element + 2 . i += 1 . >>> spisok [12, 42, 22, 32]
Но если мы вынуждены использовать счетчик, то выгода от использования цикла for не очевидна. Если знать длину списка, то почему бы не воспользоваться while . Длину можно измерить с помощью встроенной в Python функции len() .
>>> i = 0 >>> while i < len(spisok): . spisok[i] = spisok[i] + 2 # или spisok[i] += 2 . i = i + 1 # или i += 1 . >>> spisok [14, 44, 24, 34]
Кроме того, с циклом while мы избавились от переменной element .
Функция range()
Теперь пришло время познакомиться со встроенной в Python функцией range() . «Range» переводится как «диапазон». Она может принимать один, два или три аргумента. Их назначение такое же как у функции randrange() из модуля random . Если задан только один, то генерируются числа от 0 до указанного числа, не включая его. Если заданы два, то числа генерируются от первого до второго, не включая его. Если заданы три, то третье число – это шаг.
Однако, в отличие от randrange() , функция range() генерирует не одно случайное число в указанном диапазоне. Она вообще не генерирует случайные числа. Она генерирует последовательность чисел в указанном диапазоне. Так, range(5, 11) сгенерирует последовательность 5, 6, 7, 8, 9, 10. Однако это будет не структура данных типа «список». Функция range() производит объекты своего класса – диапазоны:
>>> a = range(-10, 10) >>> a range(-10, 10) >>> type(a)
Несмотря на то, что мы не видим последовательности чисел, она есть, и мы можем обращаться к ее элементам:
>>> a[0] -10 >>> a[5] -5 >>> a[15] 5 >>> a[-1] 9
Хотя изменять их нельзя, так как, в отличие от списков, объекты range() относятся к группе неизменяемых:
>>> a[10] = 100 Traceback (most recent call last): File "", line 1, in TypeError: 'range' object does not support item assignment
Цикл for и range()
Итак, зачем нам понадобилась функций range() в теме про цикл for ? Дело в том, что вместе они образуют неплохой тандем. For как цикл перебора элементов, в отличие от while , позволяет не следить за тем, достигнут ли конец структуры. Не надо вводить счетчик для этого, изменять его и проверять условие в заголовке. С другой стороны, range() дает последовательность целых чисел, которые можно использовать как индексы для элементов того же списка.
>>> range(len(spisok)) range(0, 4)
Здесь с помощью функции len() измеряется длина списка. В данном случае она равна четырем. После этого число 4 передается в функцию range() , и она генерирует последовательность чисел от 0 до 3 включительно. Это как раз индексы элементов нашего списка.
Теперь «соединим» for и range() :
>>> spisok = [14, 44, 24, 34] >>> for i in range(len(spisok)): . spisok[i] += 2 . >>> spisok [16, 46, 26, 36]
Еще раз обратим внимание, в заголовке цикла for берутся элементы вовсе не списка, а объекта range .
Практическая работа
- Заполните список случайными числами. Используйте в коде цикл for, функции range() и randint() .
- Если объект range (диапазон) передать встроенной в Python функции list() , то она преобразует его к списку. Создайте таким образом список с элементами от 0 до 100 и шагом 17.
- В заданном списке, состоящем из положительных и отрицательных чисел, посчитайте количество отрицательных элементов. Выведите результат на экран.
- Напишите программу, которая заполняет список пятью словами, введенными с клавиатуры, измеряет длину каждого слова и добавляет полученное значение в другой список. Например, список слов – [‘yes’, ‘no’, ‘maybe’, ‘ok’, ‘what’], список длин – [3, 2, 5, 2, 4]. Оба списка должны выводиться на экран.
Примеры решения и дополнительные уроки в pdf-версии курса
X Скрыть Наверх
Python. Введение в программирование
Последовательности
Операторы внутри цикла (что нужно повторить) пишут с отступом.
4 раза напечатать Hello:
for x in range(4): print('Hello') # Output: # Hello # Hello # Hello # Hello
for переменная in последовательность : — это оператор python, который перебирает по 1 элементу из последовательности и записывает ее в переменную.
x — имя переменной. Может быть любое.
range — функция python. Она возвращает последовательность целых чисел.
Не забудьте поставить двоеточие :
for x in range(4): print(x) # Output: # 0 # 1 # 2 # 3
range(4) вернет последовательность из 0, 1, 2, 3. То есть 4 целых числа, от 0 (включая) до 4 (не включая).
Чтобы напечатать эти числа в 1 строку, будем ставить после каждого числа пробел. В функции print укажем end=’ ‘ (в конце ставить пробел, а не символ новой строки, как обычно).
for x in range(4): # переменная х равна по очереди 0 1 2 3 print(x, end=' ') # печатаем значение х и пробел print() # ПОСЛЕ цикла 1 раз печатаем \n (символ новой строки) # Output: # 0 1 2 3
Функция range(3, 10) вернет последовательность чисел от 3 (включая) до 10 (НЕ включая):
for x in range(3, 10): # переменная х равна по очереди 3 4 5 6 7 8 9 print(x, end=' ') # печатаем значение х и пробел print() # печатаем символ новой строки \n # Output: # 3 4 5 6 7 8 9
Третий аргумент функции range — на сколько увеличить число: Функция range(3, 10, 2) вернет последовательность чисел от 3 (включая) до 10 (НЕ включая) +2 каждый раз:
for x in range(3, 10, 2): # переменная х равна по очереди 3 5 7 9 print(x, end=' ') # печатаем значение х и пробел print() # печатаем символ новой строки \n # Output: # 3 5 7 9
читаем и печатаем много чисел
Даны 2 целых числа. 1 число на 1 строке. Нужно прочитать эти числа и напечатать их.
x = int(input()) # читаем первую строку, преобразуем ее к целому числу y = int(input()) # читаем вторую строку, преобразуем ее к целому числу print(x) # печатаем число print(y) # печатаем число # Input: # 3 # 5 # Output: # 3 # 5
Если числа заданы на одной строке через пробел, то их читаем так:
x, y = map(int, input().split()) print(x) print(y) # Input: # 3 5 # Output: # 3 # 5
Похоже можно прочитать много чисел на строке через пробел:
a = map(int, input().split()) for x in a: print(x) # Input: # 3 5 -2 7 1 # Output: # 3 # 5 # -2 # 7 # 1
Разберем этот код:
- input() — прочитать строку ‘3 5 -2 7 1’
- input().split() — разбить прочитанную строку по пробельным символам на строки, получится список строк; [‘3’, ‘5’, ‘-2’, ‘7’, ‘1’]
- map(функция, последовательность) — применить функцию к каждому элементу последовательности, вернуть полученную последовательность. Тут получили последовательность чисел 3 5 -2 7 1. Переменная a ссылается на эту последовательность.
К полученной последовательности можно применить оператор for..in
Генераторы — 1 раз
Генераторы — это последовательности, по которым можно пройти только один раз.
a = map(int, input().split()) for x in a: # первый цикл по map print(x) print('---') # печатаем --- чтобы отделить данные первого цикла от второго for x in a: # второй цикл по той же map, map теперь пустая print(x) # Input: # 3 5 -2 # Output: # 3 # 5 # -2 # ---
Если нужно будет пройти по тем же данным несколько раз, их нужно сохранить в памяти. Например, сделать из последовательности map список list.
a = list(map(int, input().split())) for x in a: # первый цикл по списку list print(x) print('---') # печатаем --- чтобы отделить данные первого цикла от второго for x in a: # второй цикл по тому же списку print(x) # Input: # 3 5 -2 # Output: # 3 # 5 # -2 # --- # 3 # 5 # -2
:question: Зачем нужны последовательности map? Давайте сразу из map делать list.
Список хранит все свои элементы в памяти. Элементы последовательности могут вычисляться только тогда, когда потребуются («ленивые вычисления») и не занимать место в памяти. Полезно, если элементов очень много.
Еще один пример последовательностей, которые хранятся полностью в памяти — строки.
a = 'Hello' for x in a: # первый цикл по строке 'Hello' print(x) print('---') # печатаем --- чтобы отделить данные первого цикла от второго for x in a: # второй цикл по той же строке print(x) # Output: # H # e # e # l # o # --- # H # e # e # l # o
Однопроходные алгоритмы
Рассмотрим простые алгоритмы, которые в 1 проход по последовательности чисел вычисляют то, что требуется в задаче.
Сумма
Дано несколько целых чисел на 1 строке через пробел. Найти сумму этих чисел.
Сумму можно найти в один проход по последовательности чисел.
Рассмотрим более простую задачу: найдем сумму чисел 3, 7, -2:
x, y, z = 3, 7, -2 res = x + y + z print(res)
Если чисел много, то трудно придумывать имена переменных для каждого числа. Перепишем этот код так, чтобы использовать только 2 переменных. res — сумма, x — очередное слагаемое (а не первое слагаемое).
res = 0 # сначала сумма 0 x = 3 res += x print('x=', x, 'res=', res) # x= 3 res= 3 x = 7 res += x print('x=', x, 'res=', res) # x= 7 res= 10 x = -2 res += x print('x=', x, 'res=', res) # x= -2 res= 8 print(res) # 8 - печатаем ответ задачи
Видно, что есть код, который повторяется. Сделаем из него цикл.
Код, который делаем 1 раз, пишем или до или после цикла.
Будем вводить числа с клавиатуры. Все числа на 1 строке через пробел.
a = map(int, input().split()) res = 0 # до цикла сумма равна 0 for x in a: res += x print('x=', x, 'res=', res) print(res) # после окончания цикла печатаем ответ
Заметьте, этот код находит сумму любого количества чисел в строке, а не только 3 чисел.
Как мы придумали такой алгоритм?
Представим, что мы уже посчитали сумму последовательности чисел и она хранится в res . Если к последовательности добавить еще одно число (запишем его в x ), то сумма всех чисел станет res = res + x . То есть на каждом шаге цикла нужно прочитать еще одно число и добавить его к сумме.
Чему должны быть равны значения переменных ДО цикла? Представим, что чисел еще нет. Тогда их сумма 0. x до цикла нам не нужен (чисел нет). res до цикла 0.
Запишем этот алгоритм как функцию mysum от последовательности. Функция будет возвращать сумму чисел.
def mysum(a): # создаем функцию mysum res = 0 for x in a: res = res + x print('x=', x, 'res=', res) return res # конец функции mysum a = map(int, input().split()) # читаем числа с клавиатуры print('Сумма равна', mysum(a)) # вызываем функцию mysum
Заметим, что функция может находить сумму последовательности любых чисел, а не только целых чисел.
def mysum(a): # создаем функцию mysum res = 0 for x in a: res = res + x print('x=', x, 'res=', res) return res # конец функции mysum a = [3, 7, -2.5, 0.16] # зададим последователность как список чиселё print('Сумма равна', mysum(a)) # вызываем функцию mysum для этого списка # Output: # x= 3 res= 3 # x= 7 res= 10 # x= -2.5 res= 7.5 # x= 0.16 res= 7.66 # Сумма равна 7.66
Максимум
Дана последовательность чисел. Найдем максимальное число.
Сначала напишем функцию max2(x, y) , которая из двух чисел возвращает максимальное.
def max2(x, y): if x > y: return x else: return y
Будем думать как в алгоритме с суммой.
Пусть мы нашли максимальное число для последовательности и сохранили его в res . Нам дали еще одно число в переменной x . Тогда максимум из всех чисел — это максимум из res и x . То есть max2(res, x) .
def max2(x, y): # функция max2 - максимум из 2 чисел if x > y: return x else: return y def mymax(a): # функция mymax - максимум в последовательности а res = 0 for x in a: res = max2(res, x) # раньше при добавлении числа в последовательность # его надо было добавить к сумме, # теперь нужно найти максимум из нового числа и максимума предыдущих чисел print('x=', x, 'res=', res) return res a = map(int, input().split()) # читаем числа с клавиатуры print('Максимум равен', mymax(a)) # вызываем функцию mymax
Проверяем, как работает программа:
# Input: # 3 -7 12 0 # Output: # x= 3 res= 3 # x= -7 res= 3 # x= 12 res= 12 # x= 0 res= 12 # Максимум равен 12
Проверим еще раз на последовательности отрицательных чисел.
# Input: # -3 -7 -2 -10 # Output: # x= -3 res=0 # x= -7 res=0 # x= -2 res=0 # x= -10 res=0 # Максимум равен 0
Программа работает неправильно. Максимум из отрицательных чисел не может быть 0.
Мы не подумали, чему равен максимум, если чисел нет или оно одно. Если чисел еще нет, то сумма 0, если задано одно число, то сумма равна этому числу.
Если числа не заданы. Максимума у последовательности нет. А у нас в коде написано res = 0 . Ошибка.
Если задано одно число, то это число — миниумум.
Надо научиться писать значение «не число» или брать из последовательности первый элемент.
None — значение, которого нет
В Python есть специальное значение None — «этого значения нет».
Посмотрим в интерпретаторе, как раборать с None :
>>> x = None >>> x >>> print(x) None >>> type(x) >>> x is None True >>> x is not None False >>> x == None True >>> x != None False
is None и is not None — правильные проверки на None.
Если х не None, то результаты проверок:
>>> x = 7 >>> x is None False >>> x is not None True >>> x == None False >>> x != None True
Перепишем программу, которая находит максимум, через None:
def max2(x, y): # функция max2 - максимум из 2 чисел if x > y: return x else: return y def mymax(a): # функция mymax - максимум в последовательности а res = None # сначала максимума нет (None) for x in a: if res is None: # если максимума еще нет (первое число) res = x # прочитанное число (первое!) - максимум res = max2(res, x) # для первого числа res и x равны print('x=', x, 'res=', res) return res a = map(int, input().split()) # читаем числа с клавиатуры print('Максимум равен', mymax(a)) # вызываем функцию mymax
Проверяем, как работает программа:
# Input: # -3 -7 -2 -10 # Output: # x= -3 res= -3 # x= -7 res= -3 # x= -2 res= -2 # x= -10 res= -2 # Максимум равен -2
next(a) — взять следующий элемент последовательности
next(a) — функция языка питон, возвращает следующий элемент в последовательности.
Пусть последовательность — это числа 5, 12, -1. Переберем ее значения, используя функцию next.
>>> a = map(int, input().split()) 5 12 -1 >>> x = next(a) >>> x 5 >>> x = next(a) >>> x 12 >>> x = next(a) >>> x -1 >>> x = next(a) Traceback (most recent call last): File "", line 1, in StopIteration
Когда значения в последовательности закончились, функция next не смогла вернуть элемент, и кинула исключение StopIteration . Исключения мы изучим позже.
Перепишем программу поиска максимума через next:
Перепишем программу, которая находит максимум, через None:
def max2(x, y): # функция max2 - максимум из 2 чисел if x > y: return x else: return y def mymax(a): # функция mymax - максимум в последовательности а res = next(a) # пока максимум - первое число в последовательности for x in a: # начинаем перебирать со второго числа, первое уже прочитали! res = max2(res, x) print('x=', x, 'res=', res) return res a = map(int, input().split()) # читаем числа с клавиатуры print('Максимум равен', mymax(a)) # вызываем функцию mymax
Проверяем, как работает программа:
# Input: # -3 -7 -2 -10 # Output: # x= -7 res= -3 # x= -2 res= -2 # x= -10 res= -2 # Максимум равен -2
Заметим, что перебирать в for .. in мы начали с числа -7. Число -2 мы взяли из последовательности раньше.
break — закончить цикл
Даны целые числа. Есть ли среди них число 5?
Если числа 5 нет, то нужно перебрать все числа, чтобы узнать это.
Если число 5 нашли, то дальше перебирать не нужно. Мы уже нашли число.
break — закончить цикл (перейти за конец цикла)
a = map(int, input().split()) # прочитали последователность в а for x in a: # для каждого х в этих числах if x == 5: # если x равно 5 print("Есть число 5") # печатаем (один раз!) break # выходим из цикла (чтобы не печатать много раз) print(x) # печатаем каждый раз число х else: # ТОЛЬКО если break не работал print("Нет числа 5") # конец цикла # сюда выйдет break
Проверим, как работет программа:
# Input: # 3 7 -2 5 10 -33 5 5 5 # Output: # 3 # 7 # -2 # Есть число 5
Заметим, мы закончили работать на первом числе 5 и следующие числа не печатали.
# Input: # 3 7 -2 0 # Output: # 3 # 7 # -2 # 0 # Нет числа 5
В for . else и while . else часть в else работает, если в цикле не работал break.
continue — продолжить цикл со следующего шага
continue — продолжить цикл со следующего шага.
Даны целые числа. Найдем в них все числа 5.
a = map(int, input().split()) # прочитали последователность в а for x in a: # для каждого х в этих числах print(x) # печатаем каждый раз число х if x != 5: # если x ненужное число continue # пропускаем его и берем другое print("Есть число 5") # печатаем
Проверим, как работает программа:
# Input: # 3 5 7 -2 5 # Output: # 3 # 5 # Есть число 5 # 7 # -2 # 5 # Есть число 5
Разбить число на составляющие
На вход функцией input подается 6-значеное число. Нужно разбить его на на отдельные числа. Например: 123456 -> 1 2 3 4 5 6. Делается это для того, чтобы проверить эквивалентность суммы первой и второй тройки чисел (Задача о счастливом билете). В программировании я начинающий и желательно всё сделать операциями div, mod, if-else
a = int(input()) b = a//1000 one = b//100 two = b%11 three = b%10 c = a%1000 four = c//100 five = c%11 six = c%10 if (one+two+three)==(four+five+six): print ('Счастливый') else: print ('Обычный')
Отслеживать
48.6k 17 17 золотых знаков 56 56 серебряных знаков 100 100 бронзовых знаков
задан 25 мар 2016 в 4:17
175 2 2 золотых знака 2 2 серебряных знака 9 9 бронзовых знаков
9 ответов 9
Сортировка: Сброс на вариант по умолчанию
Можно, конечно, честно посчитать остатки от деления и т.д., но проще всего разбить на символы строку, а потом перевести эти символы обратно в числа. Делается это во второй строке следующей программы:
a = 123456 b = map(int, str(a)) print b if len(b)==6: print "Happy" if b[0] + b[1] + b[2] == b[3] + b[4] + b[5] else "Unhappy"
Если очень хочется честным образом делить на 10, то можно вторую строку этой программы заменить на такой фрагмент:
b = [] while a > 0: b.append(a % 10) a = a // 10 b = b[::-1] # так можно развернуть, если бы нам был важен порядок print b
Теперь по тексту Вашей программы: почему-то берётся остаток от деления на 11 (в строках two = b%11 и five = c%11 , хотя правильно было бы поделить на 10, а потом взять остаток от деления на 10 ( two = (b // 10) % 10 ). Вам надо разобраться, откуда взялось 11, так как это очень странный код.
Дополнение:
Если нам важно поддержать случаи входных значений a менее, чем шестизначных, то можно поменять всего одну строчку:
while len(b) < 6: # теперь в b заведомо будет 6 элементов
Также рекомендую изучить код из соседнего ответа (от jfs), так как в нём есть ряд интересных моментов.
Извлечь из строки числа
Дана строка, содержащая натуральные числа и слова. Необходимо сформировать список из чисел, содержащихся в этой строке. Например, задана строка "abc83 cde7 1 b 24". На выходе мы должны получить список [83, 7, 1, 24].
Решение задачи на языке программирования Python
Следует посимвольно перебирать строку. Если очередной символ цифра, надо добавить ее в новую строку. Далее проверять символы за ней, и если они тоже цифры, то добавлять их в конец этой новой подстроки из цифр. Когда очередной символ окажется не цифрой, или будет достигнут конец строки, то надо преобразовать строку из цифр в число и добавить в список.
s = input() length = len(s) integers = [] i = 0 # индекс текущего символа while i length: s_int = '' # строка для нового числа while i length and '0' s[i] '9': s_int += s[i] i += 1 i += 1 if s_int != '': integers.append(int(s_int)) print(integers)
5 dkfj78df 9 8 dkfj8 [5, 78, 9, 8, 8]
Обратите внимание, что данное решение извлекает именно числа, а не цифры. Иначе мы бы не получили число 78, а получили отдельно цифру 7 и цифру 8. Задача на извлечение цифр существенно проще.
Решение через цикл for:
a = input() num_list = [] num = '' for char in a: if char.isdigit(): num = num + char else: if num != '': num_list.append(int(num)) num = '' if num != '': num_list.append(int(num)) print(num_list)
Если в строке числа всегда отделены от слов пробелами, задача решается проще:
s = input() word_list = s.split() num_list = [] for word in word_list: if word.isnumeric(): num_list.append(int(word)) print(num_list)
Здесь происходит разделение строки на слова по пробелам. В цикле с помощью метода isnumeric каждое слово проверяется, является ли оно числом. Подобную задачу можно решить в одну строку, если использовать функцию filter .
s = input() word_list = s.split() num_list = [int(num) for num in filter( lambda num: num.isnumeric(), word_list)] print(num_list)
В функцию filter передается лямбда-выражение, проверяющее слова, и список слов. Функция возвращает список строк-чисел. Далее с помощью генератора списка строки преобразовываются в целочисленный тип.
На практике при решении подобных задач, когда надо найти и извлечь из строки что-либо, обычно пользуются регулярными выражениями. В примере ниже не обязательно, чтобы число было отделено пробелами.
import re s = input() nums = re.findall(r'\d+', s) nums = [int(i) for i in nums] print(nums)
Для поиска вещественных чисел:
import re s = input() nums = re.findall(r'\d*\.\d+|\d+', s) nums = [float(i) for i in nums] print(nums)
X Скрыть Наверх
Решение задач на Python