Как и большинство программистов, вы знаете, что после создания массива, вам нужно написать цикл для его обработки. С этим нет никаких проблем, но иногда нам не нужно использовать несколько строк для написания полного цикла for для одной простой задачи. К частью, Python это понимает и предоставляет замечательный инструмент для использования в таких ситуациях. Этот инструмент называется генератор списка (list comprehensions, списковое включение).
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Telegram Чат & Канал
Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Что это за зверь?
Списковое включение (List comprehensions) – это списки, которые генерируются с циклом for внутри. Они очень распространены в Python и выглядят примерно следующим образом:
[thing for thing in list_of_things] |
Возможно, вы еще сильнее запутались, так что сделаем шаг назад. Список содержит в себе множество вещей, но определяется между квадратными скобками. Скажем, мне нужно получить функцию, которая удваивает значения всех чисел в списке. Для начала, мне нужно создать список чисел.
Теперь создадим функцию. Назовем ее list_doubler
, так как это именно то, что она делает, и она будет принимать аргумент, который является списком, который мы будем удваивать.
def list_doubler(lst): doubled = [] for num in lst: doubled.append(num*2) return doubled |
Вызов этой функции даст нам новый список с удвоенными элементами.
my_doubled_list = list_doubler(lst) |
my_doubled_list
теперь содержит значения 42
, 4
и 186
. Эта функция простая и делает то, что нам нужно простым способом, но это пять строк, учитывая определяющую строку. Также есть переменная, с которой мы ничего не делаем, кроме как добавляем и в конце возвращаем её.
Единственная часть функции, которая по-настоящему работает – это цикл for. Цикл for тоже мало что делает, просто умножает число на 2. Это идеальный кандидат для превращения в списковое включение.
Создание спискового включения
Давайте сохраним его как функцию, которую мы будем вызывать. Нам нужно только упростить тело функции. Так как списковое включение создает списки, а списки могут быть назначены к переменным, примем это во внимание и расположим списковое включение справа от doubled
и продолжим.
doubled = [thing for thing in list_of_things] |
Хорошо, теперь нам нужно заполнить правую сторону. Как и с нормальным циклом for, а правая часть списка выглядит именно так, нам нужно назвать элементы в нашем цикле. Сначала, назовем каждый объект, и мы также будем использовать переменную списка, которая будет передана.
doubled = [thing for num in lst] |
Это не может работать в полной мере, так как элемент не является… элементом. В нашей изначальной функции мы выполнили num * 2
, так что давайте сделаем это еще раз.
doubled = [num * 2 for num in lst] |
Все что находится перед циклом for
точно внесено в список. Наконец, нам нужно вернуть наш новый список.
def list_doubler(lst): doubled = [num * 2 for num in lst] return doubled |
Запускаем нашу новую функцию.
my_doubled_list = list_doubler([12, 4, 202]) |
И да, my_doubled_list
содержит ожидаемые значения 24
, 8
и 404
. Отлично, все работает! Но так как мы создаем и моментально возвращаем переменную, давайте просто применим списковое включение напрямую.
def list_doubler(lst): return [num * 2 for num in lst] |
Хорошо, отлично, но зачем мне это нужно?
Списковые включения (генератор списка, list comprehensions) отлично подходят для случаев, когда нам нужно сохранить немного места в коде. Они также удобны в случаях, когда вам просто нужно быстро обработать списки, чтобы сэкономить время над рутинной работой с этим списком.
Они также очень полезны, если вы хотите больше узнать о функциональном программировании, но эту тему мы обсудим в будущем.
Применяем условие if в список
Давайте сделаем новую функцию, которая будет давать только длинные слова из списка. Скажем, каждое слово, которое состоит более чем из 5 букв, будет считаться длинным. Для начала пропишем их вручную.
def long_words(lst): words = [] for word in lst: if len(word) > 5: words.append(word) return words |
Мы создали переменную для хранения наших слов, применяем цикл над всеми словами в нашем списке, и проверяем длинну каждого слова. Если оно длиннее 5 букв, мы вносим слово в список, и затем, наконец, мы отсылаем список назад. Давайте попробуем.
long_words(['blog', 'Treehouse', 'Python', 'hi'])
возвращает ['Treehouse', 'Python']
. Это как раз то, чего мы и ожидали.
Хорошо, давайте перепишем это в списковое включение. Для начала, построим то, что мы и так знаем.
def long_words(lst): return [word for word in lst] |
Это возвращает нам все слова, не только те, которые длиннее 5 букв. Мы вносим условный оператор в конец цикла for.
def long_words(lst): return [word for word in lst if len(word) > 5] |
Итак, мы использовали всё то же условие if, но поместили его в конец спискового включения. Оно использует то же наименование переменной, которое мы используем для элементов в списке.
Хорошо, давайте опробуем эту версию long_words(['list', 'comprehension', 'Treehouse', 'Ken'])
возвращает ['comprehension', 'Treehouse']
.
Примеры
1. Возводим в квадрат все числа от 1 до 9. Применяем функцию range.
[x**2 for x in range(10)] |
Результат:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81] |
2. Все цифры которые делятся на 5 без остатка, в диапазоне от 0 до 100.
[x for x in range(100) if x%5 == 0] |
Результат:
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95] |
3. Все цифры которые делятся на 3 и 6 без остатка, в диапазоне от 0 до 50.
[x for x in range(50) if x%3 == 0 and x%6 != 0] |
Результат:
[3, 9, 15, 21, 27, 33, 39, 45] |
4. Первая буква из каждого слова предложения.
phrase = «Тестовое сообщение из мира Python для сообщества.» print([w[0] for w in phrase.split()]) |
Результат:
[‘Т’, ‘с’, ‘и’, ‘м’, ‘P’, ‘д’, ‘с’] |
5. Заменяем букву А
в каждом слове на #
.
phrase = «АБАЖУР, АБАЗИНСКИЙ, АБАЗИНЫ, АББАТ, АББАТИСА, АББАТСТВО» print(».join([letter if letter != ‘А’ else ‘#’ for letter in phrase])) |
Результат:
#Б#ЖУР, #Б#ЗИНСКИЙ, #Б#ЗИНЫ, #ББ#Т, #ББ#ТИС#, #ББ#ТСТВО |
Итоги
Надеюсь это руководство помогло вам понять простой способ экономии кода , который вам нужно написать для получения конкретной готовой работы с вашими списками.
Старайтесь сохранять ваши списковые включения короткими, а условия if – простыми. Несложно разглядеть решение многих ваших проблем в списковых включениях и превратить их в огромный беспорядок.
Если это только распалило ваш аппетит, посмотрим, сможете ли вы разобраться со словарными включениями самостоятельно. Они используют конструкторы dict, {:} , но они довольно похожи. Вы также можете проработать установочные включения. Также ознакомьтесь с функциональным программированием в Python, если считаете себя готовым.
Больше примеров
- https://www.python.org/dev/peps/pep-0289/
- https://legacy.python.org/dev/peps/pep-0274/
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»
I have a dictonary like
list1={'ab':10,'ba':20,'def':30}.
Now my input file contains :
ab def
ba ab
I have coded:
filename=raw_input("enter file:")
f=open(filename,'r')
ff=open(filename+'_value','w')
for word in f.read().split():
s=0
if word in list1:
ff.write(word+'t'+list1[word]+'n');
s+=int(list1[word])
else:
ff.write(word+'n')
ff.write("n"+"total:%d"%(s)+"n")
Now I want my output file to contain:
ab 10
def 30
total: 40ba 20
ab 10
total: 30
Am not able to loop it for each line. How should I do it? I tried a few variations using f.readlines(), f.read(), and tried looping once, then twice with them. But I cannot get it right.
asked Jun 13, 2014 at 10:19
charvicharvi
2111 gold badge5 silver badges15 bronze badges
6
Instead of giving the answer right away, Let me give you a gist of what you ask:
To read the whole file:
f = open('myfile','r')
data = f.read()
To loop through each line in the file:
for line in data:
To loop through each word in the line:
for word in line.split():
Use it wisely to get what you want.
answered Jun 13, 2014 at 10:35
Aswin MurugeshAswin Murugesh
10.7k10 gold badges39 silver badges69 bronze badges
You need to make 2 loops and not only one:
filename = raw_input("enter file:")
with open(filename, 'r') as f, open(filename + '_value','w') as ff:
# Read each line sequentially
for line in f.read():
# In each line, read each word
total = 0
for word in line.split():
if word in list1:
ff.write("%st%sn" % (word, list1[word]))
total += int(list1[word])
else:
ff.write(word+'n')
ff.write("ntotal: %sn" % total)
I have also cleaned a little bit your code to be more readable. Also see What is the python «with» statement designed for? if you want to understand the with
block
answered Jun 13, 2014 at 10:28
Maxime LorantMaxime Lorant
33.9k19 gold badges86 silver badges96 bronze badges
5
with open("in.txt","r") as f:
with open("out.txt","w") as f1:
for line in f:
words = line.split() # split into list of two words
f1.write("{} {}n".format((words[0]),list1[words[0]])) # write first word plus value
f1.write("{} {}n".format((words[1]),list1[words[1]])) # second word plus value
f1.write("Total: {}n".format((int(list1[words[0]]) + int(list1[words[1]])))) # finally add first and second and get total
answered Jun 13, 2014 at 10:42
Given a String comprising of many words separated by space, write a Python program to iterate over these words of the string.
Examples:
Input: str = “GeeksforGeeks is a computer science portal for Geeks”
Output: GeeksforGeeks is a computer science portal for GeeksInput: str = “Geeks for Geeks”
Output: Geeks for Geeks
Method 1: Using split() Using split() function, we can split the string into a list of words and is the most generic and recommended method if one wished to accomplish this particular task. But the drawback is that it fails in the cases in string contains punctuation marks.
Python3
test_string
=
"GeeksforGeeks is a computer science portal for Geeks"
print
(
"The original string is : "
+
test_string)
res
=
test_string.split()
print
(
"nThe words of string are"
)
for
i
in
res:
print
(i)
Output
The original string is : GeeksforGeeks is a computer science portal for Geeks The words of string are GeeksforGeeks is a computer science portal for Geeks
Time complexity: O(n)
Auxiliary Space: O(n)
Method 2: Using re.findall() In the cases which contain all the special characters and punctuation marks, as discussed above, the conventional method of finding words in a string using split can fail and hence requires regular expressions to perform this task. findall() function returns the list after filtering the string and extracting words ignoring punctuation marks.
Python3
import
re
test_string
=
"GeeksforGeeks is a computer science portal for Geeks !!!"
print
(
"The original string is : "
+
test_string)
res
=
re.findall(r
'w+'
, test_string)
print
(
"nThe words of string are"
)
for
i
in
res:
print
(i)
Output
The original string is : GeeksforGeeks is a computer science portal for Geeks !!! The words of string are GeeksforGeeks is a computer science portal for Geeks
Method 3: Using for loop and string slicing
Python3
test_string
=
"GeeksforGeeks is a computer science portal for Geeks"
print
(
"The original string is: "
+
test_string)
start
=
0
for
i
in
range
(
len
(test_string)):
if
test_string[i]
=
=
' '
:
print
(test_string[start:i])
start
=
i
+
1
print
(test_string[start:])
Output
The original string is: GeeksforGeeks is a computer science portal for Geeks GeeksforGeeks is a computer science portal for Geeks
This approach uses a for loop to iterate through the characters in the string and a variable to keep track of the starting index of the current word. When a space is encountered, the current word is printed and the starting index is updated to the next character. The last word in the string is printed outside the loop.
Time Complexity: O(n)
Auxiliary Space : O(n)
Method 4: Using the split() method with a regular expression
Use the split() method with a regular expression to split the string into words
Step-by-step approach:
- Initialize a list to store the words extracted from the string.
- Use the split() method with a regular expression to split the string into words.
- Iterate over the words and append them to the list.
- Print the list of words.
Follow the below steps to implement the above idea:
Python3
import
re
test_string
=
"GeeksforGeeks is a computer science portal for Geeks !!!"
print
(
"The original string is : "
+
test_string)
res
=
re.split(r
'W+'
, test_string)
words
=
[]
for
word
in
res:
if
word:
words.append(word)
print
(
"nThe words of string are"
)
for
word
in
words:
print
(word)
Output
The original string is : GeeksforGeeks is a computer science portal for Geeks !!! The words of string are GeeksforGeeks is a computer science portal for Geeks
Time complexity: O(n), where n is the length of the input string.
Auxiliary space: O(n), where n is the length of the input string.
Цикл for в Python – это итеративная функция. Если у вас есть объект последовательности, например список, вы можете использовать цикл for для перебора элементов, содержащихся в списке.
Функциональность цикла for не сильно отличается от того, что вы видите во многих других языках программирования.
Содержание
- Базовый синтаксис
- Как вывести отдельные буквы строки?
- Использование цикла for для перебора списка или кортежа
- Вложенный цикл
- Использование с функцией range()
- Оператор break
- Оператор continue
- С (необязательным) блоком else
Базовый синтаксис
Мы можем использовать цикл for для перебора списка, кортежа или строк. Синтаксис:
for itarator_variable in sequence_name: Statements . . . Statements
Как вывести отдельные буквы строки?
Строка Python – это последовательность символов. Мы можем использовать цикл for для перебора символов и их печати.
word="anaconda" for letter in word: print (letter)
Вывод:
a n a c o n d a
Список и кортеж – повторяемые объекты. Мы можем использовать цикл для перебора их элементов.
words= ["Apple", "Banana", "Car", "Dolphin" ] for word in words: print (word)
Вывод:
Apple Banana Car Dolphin
Давайте посмотрим на пример, чтобы найти сумму чисел в кортеже:
nums = (1, 2, 3, 4) sum_nums = 0 for num in nums: sum_nums = sum_nums + num print(f'Sum of numbers is {sum_nums}') # Output # Sum of numbers is 10
Вложенный цикл
Когда у нас есть цикл for внутри другого цикла for, он называется вложенным циклом for. В следующем коде показаны вложенные циклы:
words= ["Apple", "Banana", "Car", "Dolphin" ] for word in words: #This loop is fetching word from the list print ("The following lines will print each letters of "+word) for letter in word: #This loop is fetching letter for the word print (letter) print("") #This print is used to print a blank line
Вывод
Использование с функцией range()
Python range() – одна из встроенных функций. Она используется с циклом for для выполнения блока кода определенное количество раз.
for x in range(3): print("Printing:", x) # Output # Printing: 0 # Printing: 1 # Printing: 2
Мы также можем указать параметры запуска, остановки и шага для функции диапазона.
for n in range(1, 10, 3): print("Printing with step:", n) # Output # Printing with step: 1 # Printing with step: 4 # Printing with step: 7
Оператор break
Оператор break используется для преждевременного выхода из цикла for. Он используется для прерывания цикла при выполнении определенного условия.
Допустим, у нас есть список чисел, и мы хотим проверить, присутствует ли число. Мы можем перебрать список чисел и, если число найдено, выйти из цикла, потому что нам не нужно продолжать перебирать оставшиеся элементы.
В этом случае мы будем использовать условие if else.
nums = [1, 2, 3, 4, 5, 6] n = 2 found = False for num in nums: if n == num: found = True break print(f'List contains {n}: {found}') # Output # List contains 2: True
Оператор continue
Мы можем использовать операторы continue внутри цикла, чтобы пропустить выполнение тела цикла for для определенного условия.
Допустим, у нас есть список чисел, и мы хотим вывести сумму положительных чисел. Мы можем использовать операторы continue, чтобы пропустить цикл для отрицательных чисел.
nums = [1, 2, -3, 4, -5, 6] sum_positives = 0 for num in nums: if num < 0: continue sum_positives += num print(f'Sum of Positive Numbers: {sum_positives}')
С (необязательным) блоком else
Блок else выполняется только в том случае, если цикл не завершается оператором break.
Допустим, у нас есть функция для вывода суммы чисел, когда все числа четные. Мы можем использовать оператор break, чтобы завершить цикл for, если присутствует нечетное число. Мы можем вывести сумму в части else, чтобы она выводилась, когда цикл выполняется нормально.
def print_sum_even_nums(even_nums): total = 0 for x in even_nums: if x % 2 != 0: break total += x else: print("For loop executed normally") print(f'Sum of numbers {total}') # this will print the sum print_sum_even_nums([2, 4, 6, 8]) # this won't print the sum because of an odd number in the sequence print_sum_even_nums([2, 4, 5, 8]) # Output # For loop executed normally # Sum of numbers 20
( 3 оценки, среднее 5 из 5 )
Содержание:развернуть
- Применение циклов
- Итерации
- Синтаксис for
- range() и enumerate()
- break и continue
- else
- Best practice
-
Цикл по списку
-
Цикл по словарю
-
Цикл по строке
-
Как сделать цикл for с шагом
-
Обратный цикл for
-
for в одну строку
Циклы являются мощнейшим инструментом, предоставляемым высокоуровневыми языками программирования. Эти управляющие конструкции позволяют многократно выполнять требуемую последовательность инструкций. Циклы в языке Python представлены двумя основными конструкциями: while
и for
.
Подробнее о циклах while вы можете прочитать здесь:
Применение циклов
Концепция циклов — это не просто очередная абстрактная выдумка программистов. Повторяющиеся раз за разом операции окружают нас и в реальной жизни:
🥣 добавление щепотки приправ в варящийся бульон и помешивание его до тех пор, пока пакетик специй не закончится.
🕙 следование строгому расписанию каждый будний день, пока не наступят долгожданные выходные.
🌄 даже банальная смена времён года.
— всё это циклы, и представить нормальную жизнь без них попросту невозможно.
Впрочем, то же касается и программирования. Представьте, что вам нужно последовательно напечатать числа от 1 до 9999999999. В отсутствии циклов, эту задачу пришлось бы выполнять ручками, что потребовало бы колоссального количества кода и огромных временных затрат:
print(1)
print(2)
print(3)
# ...
# 9999999995 строк
# ...
print(9999999998)
print(9999999999)
Циклы же позволяют уместить такую многокилометровую запись в изящную и простую для понимания конструкцию, состоящую всего из двух строчек:
for i in range(1, 10000000000):
print(i)
Смысл её крайне прост. В основе цикла for
лежат последовательности, и в примере выше это последовательность чисел от 1 до 9999999999. for
поэлементно её перебирает и выполняет код, который записан в теле цикла. В частности, для решения данной задачи туда была помещена инструкция, позволяющая выводить значение элемента последовательности на экран.
Итерации
- Итерация (Iteration) — это одно из повторений цикла (один шаг или один «виток» циклического процесса). К примеру цикл из 3-х повторений можно представить как 3 итерации.
- Итерируемый объект (Iterable) — объект, который можно повторять. Проще говоря это объект, который умеет отдавать по одному результату за каждую итерацию.
- Итератор (iterator) — итерируемый объект, в рамках которого реализован метод __next__, позволяющий получать следующий элемент.
👉 Чтобы выполнить итерацию, Python делает следующее:
- Вызывает у итерируемого объекта метод
iter()
, тем самым получая итератор. - Вызывает метод
next()
, чтобы получить каждый элемент от итератора. - Когда метод next возвращает исключение
StopIteration
, цикл останавливается.
Пример создания итерируемого объекта
Для того чтобы создать собственный класс итерируемого объекта, нужно всего лишь внутри него реализовать два метода: __iter__() и __next__():
- внутри метода __next__ () описывается процедура возврата следующего доступного элемента;
- метод __iter__() возвращает сам объект, что даёт возможность использовать его, например, в циклах с поэлементным перебором.
Создадим простой строковый итератор, который на каждой итерации, при получении следующего элемента (т.е. символа), приводит его к верхнему регистру:
class ToUpperCase:
def __init__(self, string_obj, position=0):
"""сохраняем строку, полученную из конструктора,
в поле string_obj и задаём начальный индекс"""
self.string_obj = string_obj
self.position = position
def __iter__(self):
""" возвращаем сам объект """
return self
def __next__(self):
""" метод возвращает следующий элемент,
но уже приведенный к верхнему регистру """
if self.position >= len(self.string_obj):
# исключение StopIteration() сообщает циклу for о завершении
raise StopIteration()
position = self.position
# инкрементируем индекс
self.position += 1
# возвращаем символ в uppercase-e
return self.string_obj[position].upper()
low_python = "python"
high_python = ToUpperCase(low_python)
for ch in high_python:
print(ch, end="")
> PYTHON
Синтаксис for
Как было замечено, цикл for
python — есть средство для перебора последовательностей. С его помощью можно совершать обход строк, списков, кортежей и описанных выше итерируемых объектов.
В простейшем случае он выглядит так:
for item in collection:
# do something
Если последовательность collection
состоит, скажем, из 10 элементов, for
будет поочерёдно обходить их, храня значение текущего элемента в переменной item
.
Принцип работы for
максимально схож с таковым у циклов foreach
, применяемых во многих других высокоуровневых языках.
aliceQuote = "The best way to explain it is to do it."
# с помощью цикла for посчитаем количество символов (с пробелами) в строке
# зададим счетчик
count = 0
# будем посимвольно обходить весь текст
for letter in aliceQuote:
# на каждой новой итерации:
# в переменной letter будет храниться следующий символ предложения;
# увеличиваем счетчик на 1;
count += 1
print(count)
> 39
range() и enumerate()
Вы уже наверняка запомнили, что for
работает с последовательностями. В программировании очень часто приходится повторять какую-то операцию фиксированное количество раз. А где упоминается «количество чего-то», существует и последовательность, числовая.
👉 Для того чтобы выполнить какую-либо инструкцию строго определенное число раз, воспользуемся функцией range()
:
# скажем Миру привет целых пять раз!
for i in range(5):
print("Hello World!")
>
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
range()
можно представлять, как функцию, что возвращает последовательность чисел, регулируемую количеством переданных в неё аргументов. Их может быть 1, 2 или 3:
range(stop)
;range(start, stop)
;range(start, stop, step)
.
Здесь start
— это первый элемент последовательности (включительно), stop
— последний (не включительно), а step
— разность между следующим и предыдущим членами последовательности.
# 0 - начальный элемент по умолчанию
for a in range(3):
print(a)
>
0
1
2
# два аргумента
for b in range(7, 10):
print(b)
>
7
8
9
# три аргумента
for c in range(0, 13, 3):
print(c)
>
0
3
6
9
12
Подробнее о функции range тут:
👉 Чрезвычайно полезная функция enumerate()
определена на множестве итерируемых объектов и служит для создания кортежей на основании каждого из элементов объекта. Кортежи строятся по принципу (индекс элемента, элемент), что бывает крайне удобно, когда помимо самих элементов требуется ещё и их индекс.
# заменим каждый пятый символ предложения, начиная с 0-го, на *
text = "Это не те дроиды, которых вы ищете"
new_text = ""
for char in enumerate(text):
if char[0] % 5 == 0:
new_text += '*'
else:
new_text += char[1]
print(new_text)
> *то н* те *роид*, ко*орых*вы и*ете
break и continue
Два похожих оператора, которые можно встретить и в других языках программирования.
break
— прерывает цикл и выходит из него;continue
— прерывает текущую итерацию и переходит к следующей.
# break
for num in range(40, 51):
if num == 45:
break
print(num)
>
40
41
42
43
44
Здесь видно, как цикл, дойдя до числа 45 и вернув истину в условном выражении, прерывается и заканчивает свою работу.
# continue
for num in range(40, 51):
if num == 45:
continue
print(num)
>
40
41
42
43
44
46
47
48
49
50
В случае continue
происходит похожая ситуация, только прерывается лишь одна итерация, а сам же цикл продолжается.
else
Если два предыдущих оператора можно часто встречать за пределами Python, то else
, как составная часть цикла, куда более редкий зверь. Эта часть напрямую связана с оператором break
и выполняется лишь тогда, когда выход из цикла был произведен НЕ через break
.
group_of_students = [21, 18, 19, 21, 18]
for age in group_of_students:
if age < 18:
break
else:
print('Всё в порядке, они совершеннолетние')
> Всё в порядке, они совершеннолетние
Best practice
Цикл по списку
Перебрать list
в цикле не составляет никакого труда, поскольку список — объект итерируемый:
# есть список
entities_of_warp = ["Tzeench", "Slaanesh", "Khorne", "Nurgle"]
# просто берём список, «загружаем» его в цикл и без всякой задней мысли делаем обход
for entity in entities_of_warp:
print(entity)
>
Tzeench
Slaanesh
Khorne
Nurgle
Так как элементами списков могут быть другие итерируемые объекты, то стоит упомянуть и о вложенных циклах. Цикл внутри цикла вполне обыденное явление, и хоть количество уровней вложенности не имеет пределов, злоупотреблять этим не следует. Циклы свыше второго уровня вложенности крайне тяжело воспринимаются и читаются.
strange_phonebook = [
["Alex", "Andrew", "Aya", "Azazel"],
["Barry", "Bill", "Brave", "Byanka"],
["Casey", "Chad", "Claire", "Cuddy"],
["Dana", "Ditrich", "Dmitry", "Donovan"]
]
# это список списков, где каждый подсписок состоит из строк
# следовательно можно (зачем-то) применить тройной for
# для посимвольного чтения всех имён
# и вывода их в одну строку
for letter in strange_phonebook:
for name in letter:
for character in name:
print(character, end='')
> A l e x A n d r e w A y a A z a z e l B a r ...
Цикл по словарю
Чуть более сложный пример связан с итерированием словарей. Обычно, при переборе словаря, нужно получать и ключ и значение. Для этого существует метод .items()
, который создает представление в виде кортежа для каждого словарного элемента.
Цикл, в таком случае, будет выглядеть следующим образом:
# создадим словарь
top_10_largest_lakes = {
"Caspian Sea": "Saline",
"Superior": "Freshwater",
"Victoria": "Freshwater",
"Huron": "Freshwater",
}
# обойдём его в цикле for и посчитаем количество озер с солёной водой и количество озёр с пресной
salt = 0
fresh = 0
# пара "lake, water", в данном случае, есть распакованный кортеж, где lake - ключ словаря, а water - значение.
# цикл, соответственно, обходит не сам словарь, а его представление в виде пар кортежей
for lake, water in top_10_largest_lakes.items():
if water == 'Freshwater':
fresh += 1
else:
salt += 1
print("Amount of saline lakes in top10: ", salt)
print("Amount of freshwater lakes in top10: ", fresh)
> Amount of saline lakes in top10: 1
> Amount of freshwater lakes in top10: 3
Цикл по строке
Строки, по сути своей — весьма простые последовательности, состоящие из символов. Поэтому обходить их в цикле тоже совсем несложно.
word = 'Alabama'
for w in word:
print(w, end=" ")
> A l a b a m a
Как сделать цикл for с шагом
Цикл for
с шагом создается при помощи уже известной нам функции range
, куда, в качестве третьего по счету аргумента, нужно передать размер шага:
# выведем числа от 100 до 1000 с шагом 150
for nums in range(100, 1000, 150):
print(nums)
>
100
250
400
550
700
850
Обратный цикл for
Если вы еще не убедились в том, что range()
полезна, то вот ещё пример: благодаря этой функции можно взять и обойти последовательность в обратном направлении.
# выведем числа от 40 до 50 по убыванию
# для этого установим step -1
for nums in range(50, 39, -1):
print(nums)
>
50
49
48
47
46
45
44
43
42
41
40
for в одну строку
Крутая питоновская фишка, основанная на так называемых list comprehensions
или, по-русски, генераторов. Их запись, быть может, несколько сложнее для понимания, зато очевидно короче и, по некоторым данным, она работает заметно быстрее на больших массивах данных.
В общем виде генератор выглядит так:
[результирующее выражение | цикл | опциональное условие]
Приведем пример, в котором продублируем каждый символ строки inputString
:
# здесь letter * 2 — результирующее выражение; for letter in inputString — цикл, а необязательное условие опущено
double_letter = [letter * 2 for letter in "Banana"]
print(double_letter)
> ['BB', 'aa', 'nn', 'aa', 'nn', 'aa']
Другой пример, но теперь уже с условием:
# создадим список, что будет состоять из четных чисел от нуля до тридцати
# здесь if x % 2 == 0 — необязательное условие
even_nums = [x for x in range(30) if x % 2 == 0]
print(even_nums)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28]
—
Processing Every Word in a File
Credit: Luther Blissett
Problem
You need to do something to every word in a
file, similar to the foreach
function of
csh.
Solution
This is best handled by two nested loops, one on lines and one on the
words in each line:
for line in open(thefilepath).xreadlines( ): for word in line.split( ): dosomethingwith(word)
This implicitly defines words as sequences of nonspaces separated by
sequences of spaces (just as the Unix program wc
does). For other definitions of words, you can use regular
expressions. For example:
import re re_word = re.compile(r'[w-]+') for line in open(thefilepath).xreadlines( ): for word in re_word.findall(line): dosomethingwith(word)
In this case, a word is defined as a maximal sequence of
alphanumerics and hyphens.
Discussion
For other definitions of words you will obviously need different
regular expressions. The outer loop, on all lines in the file, can of
course be done in many ways. The xreadlines
method
is good, but you can also use the list obtained by the
readlines
method, the standard library module
fileinput
, or, in Python 2.2, even just:
for line in open(thefilepath):
which is simplest and fastest.
In Python 2.2, it’s often a good idea to wrap
iterations as iterator objects, most commonly by simple generators:
from _ _future_ _ import generators def words_of_file(thefilepath): for line in open(thefilepath): for word in line.split( ): yield word for word in words_of_file(thefilepath): dosomethingwith(word)
This approach lets you separate, cleanly and effectively, two
different concerns: how to iterate over all items (in this case,
words in a file) and what to do with each item in the iteration. Once
you have cleanly encapsulated iteration concerns in an iterator
object (often, as here, a generator), most of your uses of iteration
become simple for
statements. You can often reuse
the iterator in many spots in your program, and if maintenance is
ever needed, you can then perform it in just one place—the
definition of the iterator—rather than having to hunt for all
uses. The advantages are thus very similar to those you obtain, in
any programming language, by appropriately defining and using
functions rather than copying and pasting pieces of code all over the
place. With Python 2.2’s iterators, you can get
these advantages for looping control structures, too.