For word in words python

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 Geeks 

Input: 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.

I wanted to know how to iterate through a string word by word.

string = "this is a string"
for word in string:
    print (word)

The above gives an output:

t
h
i
s

i
s

a

s
t
r
i
n
g

But I am looking for the following output:

this
is
a
string

Pavel's user avatar

Pavel

5,0804 gold badges29 silver badges53 bronze badges

asked Aug 6, 2015 at 1:41

m0bi5's user avatar

1

When you do —

for word in string:

You are not iterating through the words in the string, you are iterating through the characters in the string. To iterate through the words, you would first need to split the string into words , using str.split() , and then iterate through that . Example —

my_string = "this is a string"
for word in my_string.split():
    print (word)

Please note, str.split() , without passing any arguments splits by all whitespaces (space, multiple spaces, tab, newlines, etc).

Olivier Pons's user avatar

Olivier Pons

15.3k26 gold badges118 silver badges211 bronze badges

answered Aug 6, 2015 at 1:43

Anand S Kumar's user avatar

Anand S KumarAnand S Kumar

87.3k18 gold badges183 silver badges172 bronze badges

2

This is one way to do it:

string = "this is a string"
ssplit = string.split()
for word in ssplit:
    print (word)

Output:

this
is
a
string

answered Aug 6, 2015 at 1:45

Joe T. Boka's user avatar

Joe T. BokaJoe T. Boka

6,5046 gold badges27 silver badges48 bronze badges

for word in string.split():
    print word

answered Aug 6, 2015 at 1:50

Connor's user avatar

ConnorConnor

1346 bronze badges

2

Using nltk.

from nltk.tokenize import sent_tokenize, word_tokenize
sentences = sent_tokenize("This is a string.")
words_in_each_sentence = word_tokenize(sentences)

You may use TweetTokenizer for parsing casual text with emoticons and such.

answered Oct 16, 2019 at 21:24

noɥʇʎԀʎzɐɹƆ's user avatar

noɥʇʎԀʎzɐɹƆnoɥʇʎԀʎzɐɹƆ

9,6992 gold badges47 silver badges65 bronze badges

One way to do this is using a dictionary. The problem for the code above is it counts each letter in a string, instead of each word. To solve this problem, you should first turn the string into a list by using the split() method, and then create a variable counts each comma in the list as its own value. The code below returns each time a word appears in a string in the form of a dictionary.

    s = input('Enter a string to see if strings are repeated: ')
    d = dict()
    p = s.split()
    word = ','
    for word in p:
        if word not in d:
            d[word] = 1
        else:
            d[word] += 1
    print (d)

answered Nov 17, 2021 at 2:55

The_Chosen_One69's user avatar

s = 'hi how are you'
l = list(map(lambda x: x,s.split()))
print(l)

Output: ['hi', 'how', 'are', 'you']

answered Dec 11, 2019 at 15:56

Nanda Thota's user avatar

Nanda ThotaNanda Thota

3023 silver badges10 bronze badges

You can try this method also:

sentence_1 = «This is a string»

list = sentence_1.split()

for i in list:

print (i)

answered Aug 9, 2022 at 9:31

Samartha Chakrawarti's user avatar

2

Цикл for в Python – это итеративная функция. Если у вас есть объект последовательности, например список, вы можете использовать цикл for для перебора элементов, содержащихся в списке.

Функциональность цикла for не сильно отличается от того, что вы видите во многих других языках программирования.

Содержание

  1. Базовый синтаксис
  2. Как вывести отдельные буквы строки?
  3. Использование цикла for для перебора списка или кортежа
  4. Вложенный цикл
  5. Использование с функцией range()
  6. Оператор break
  7. Оператор continue
  8. С (необязательным) блоком 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, цикл останавливается.

Схема работы цикла «for» в Python

Пример создания итерируемого объекта
Для того чтобы создать собственный класс итерируемого объекта, нужно всего лишь внутри него реализовать два метода: __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]

В этой статье мы разберем, работу цикла for в Python.

Мы начнем с пары основных примеров и их синтаксиса. Далее обсудим, когда может быть полезен блок else, связанный с циклом for. Затем мы разберем итерактивные объекты (iterable), итераторы (iterator) и протокол итератора. Также узнаем, как создавать собственные итераторы и итерируемые объекты. После этого мы обсудим, как цикл for реализован с использованием итерактивных объектов и итераторов. Потом мы рассмотрим реализацию логики цикла for, используя цикл while и используя протокол итератора.
И наконец, для тех, кому интересно, мы разберем простой цикл for и пройдемся по инструкциям, которые интерпретатор Python выполняет при выполнении цикла for. Это должно помочь понять, что именно происходит внутри, во время работы цикла for.

Оператор for является одним из двух операторов, используемых для создания циклов в Python, другим является оператор while. Если вы совсем не знакомы с итерациями в Python, то рекомендуем почитать статью Итерации в Python: операторы for, while, break и continue которая будет хорошей отправной точкой для изучения циклов и итераций.

Простой цикл for

Давайте начнем с простого цикла for, который перебирает список строк и печатает каждую строку.

>>> for word in ["You", "are", "awesome!"]:
...   print(word)
...
You
are
awesome!

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

Цикл for с условием else

В Python цикл for может иметь необязательное условие else. Кодовый блок в предложении else выполняется после завершения цикла for, то есть после того, как все элементы итерируемого элемента были исчерпаны. Теперь давайте посмотрим, как мы можем расширить предыдущий пример, чтобы включить условие else.

>>> for word in ["You", "are", "awesome!"]:
...   print(word)
... else:
...   print("See you later!")
...
You
are
awesome!
See you later!

Когда полезно условие else?

Как вы могли заметить, блок else выполняется после завершения цикла for. Так какой смысл использовать блок else? Разве не будет выполнен следующий набор операторов после цикла for?

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

def search(search_list, search_item):
  found_item = False

  for word in search_list:
    if word == search_item:
      found_item = True
      print("Found word '{}'".format(search_item))
      break

  if not found_item:
    print("Word '{}' was not found!".format(search_item))

Использование:

>>> search(["You", "are", "awesome!"], "are")
Found word 'are'
>>> search(["You", "are", "awesome!"], "we")
Word 'we' was not found!

С помощью блока else мы можем избежать использования логического флага found_item. Давайте посмотрим, как мы можем переписать вышеуказанный метод с помощью else. Обратите внимание, что блок else будет пропущен, если в цикле for встречается оператор break.

def search(search_list, search_item):
  for word in search_list:
    if word == search_item:
      print("Found word '{}'".format(search_item))
      break
  else:
    print("Word '{}' was not found!".format(search_item))

Таким образом, блок else действительно полезен, только если у нас есть оператор break в цикле for, и нам нужно, чтобы выполнился набор операторов, если условие break никогда не выполнялось.

В противном случае операторы, связанные с else, просто выполняются в конце цикла for. Вы увидите это, когда мы разберем байт-код в последнем разделе этой статьи.

Синтаксис цикла for

Теперь, когда мы рассмотрели несколько основных примеров, давайте завершим этот раздел синтаксисом цикла for.

for <element> in <iterable>:
    <set_of_statements_1>
else:
    <set_of_statements_2>

По сути, для каждого итерируемого элемента выполняется set_of_statements_1. Как только все элементы исчерпаны, управление переходит к блоку else и выполняется set_of_statements_2.

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

Итерируемые объекты (iterables) и итераторы (iterators)

Итерируемые объекты

В предыдущем разделе мы использовали термин «iterables» для обозначения объекта, который итерировался циклом for. Теперь давайте попробуем понять, что такое итерируемый объект в Python.

В Python итерируемый объект – это любой объект, который можно использовать в итерации с использованием цикла for. Это означает, что объект должен возвращать итератор при передаче в метод iter(). Давайте посмотрим примеры некоторых часто используемых встроенных итерируемых объектов в Python.

>>> iter("You are awesome!") # String
<str_iterator object at 0x1041ad2e8>
>>> iter(["You", "are", "awesome!"]) # List
<list_iterator object at 0x1041ad358>
>>> iter(("You", "are", "awesome!")) # Tuple
<tuple_iterator object at 0x1041ad390>
>>> iter({"You", "are", "awesome!"}) # Set
<set_iterator object at 0x1041ac678>
>>> iter({1: "You", 2: "are", 3: "awesome!"}) # Dictionary
<dict_keyiterator object at 0x10400df48>
>>> iter(range(3)) # Range function
<range_iterator object at 0x1041a1450>

Как вы можете видеть, когда мы вызываем iter() для итерируемого объекта, он возвращает объект итератора.

Итераторы

А что такое итератор? В Python итератор определяется как объект, представляющий поток данных. По сути, если мы передаем итератор во встроенный метод next(), он должен вернуть следующее значение из связанного потока данных. Когда все элементы исчерпаны, должно появиться исключение StopIteration. Он должен продолжать вызывать исключение StopIteration для любых последующих вызовов метода next().

Примеры итератора со списком.

>>> my_list = ["You", "are", "awesome!"]
>>>
>>> # Get the iterator.
... list_iterator = iter(my_list)
>>>
>>> # Get next element of iterator.
... next(list_iterator)
'You'
>>> next(list_iterator)
'are'
>>> next(list_iterator)
'awesome!'
>>> next(list_iterator)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> next(list_iterator)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Итераторы тоже итеративные объекты! Но..

Следует помнить одну интересную вещь: итераторы сами по себе также поддерживают (обязаны поддерживать согласно протоколу итератора) метод iter(). Это означает, что мы можем вызвать метод iter() для итератора и получить сам объект итератора.

>>> my_list = ["You", "are", "awesome!"]
>>> list_iterator = iter(my_list)
>>> list_iterator
<list_iterator object at 0x1099a6320>
>>> iterator_of_iterator = iter(list_iterator)
>>> iterator_of_iterator
<list_iterator object at 0x1099a6320>

Таким образом, мы можем использовать итераторы везде, где ожидается итерация, например, в цикле for.

Однако обратите внимание, что вызов iter() для объекта-контейнера, такого как list, каждый раз будет возвращать новый итератор. Но вызов iter() для итератора просто возвращает тот же объект.

>>> my_list = [1, 2]
>>> iter(my_list)
<list_iterator object at 0x1099a62b0>
>>> iter(my_list) # This gives a fresh iterator object
<list_iterator object at 0x1099a62e8>
>>> my_list = [1, 2]
>>> list_iter = iter(my_list)
>>> list_iter
<list_iterator object at 0x1099a62b0>
>>> iter(list_iter) # This returns the same iterator object
<list_iterator object at 0x1099a62b0>
>>> iter(list_iter) # This returns the same iterator object
<list_iterator object at 0x1099a62b0>

Итерация по списку дважды

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

>>> my_list = ["You are Awesome!"]
>>>
>>> for word in my_list:
...   print(word)
...
You are Awesome!
>>> for word in my_list:
...   print(word)
...
You are Awesome!

Итерация через list_iterator дважды

Обратите внимание, что итератор будет исчерпан в первом цикле, а во второй раз мы просто видим пустой контейнер.

>>> my_list = ["You are Awesome!"]
>>> list_iterator = iter(my_list)
>>>
>>> for word in list_iterator:
...   print(word)
...
You are Awesome!
>>>
>>> for word in list_iterator:
...   print(word)
...
>>>

Протокол итератора

В предыдущем разделе мы увидели, что:

  1. Итерируемый объект при передаче в функцию iter() возвращает итератор.
  2. Итератор,
    1. при передаче в функцию next() возвращает следующий элемент или вызывает StopIteration после того, как все элементы будут исчерпаны.
    2. при передаче функции iter() возвращает себя.

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

  1. __next()__
    • Этот метод должен возвращать следующий элемент серии каждый раз, когда он вызывается. Как только все элементы исчерпаны, должно появиться исключение StopIteration.
    • Этот метод вызывается изнутри, когда мы вызываем встроенный метод next().
  2. __iter()__
    • Этот метод должен возвращать сам объект итератора.
    • Это метод, который вызывается внутри, когда мы вызываем встроенный метод iter().

Создание своего собственного итератора

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

class Range:
  def __init__(self, start, stop, step):
    self.next = start
    self.stop = stop
    self.step = step

  def __next__(self):
    if self.next > self.stop:
      raise StopIteration
    next_item = self.next
    self.next += self.step
    return next_item

  def __iter__(self):
    return self

Теперь посмотрим, как он работает с циклом for.

>>> for num in Range(1, 10, 2):
...   print(num)
...
1
3
5
7
9

Обратите внимание, что экземпляр Range является как итерируемым объектом, так и итератором.

Создание своего собственного итерируемого объекта

Все, что для этого нужно, это возвращать новый итератор всякий раз, когда вызывается метод __iter__() , т. е. в этом случае он должен возвращать новый экземпляр Range.

class RangeIterable:
  def __init__(self, start, stop, step):
    self.start = start
    self.stop = stop
    self.step = step

  def __iter__(self):
    return Range(self.start, self.stop, self.step)

Давайте теперь используем наш RangeIterable с циклом for.

>>> for num in RangeIterable(1, 10, 2):
...   print(num)
...
1
3
5
7
9

Как работает цикл for?

Теперь, когда мы поняли, что такое итератор и итерируемый объект, мы можем глубже понять, как на самом деле работает цикл for.

Давайте снова посмотрим на наш предыдущий пример.

>>> for word in ["You", "are", "awesome!"]:
...   print(word)
... else:
...   print("See you later!")
...
You
are
awesome!
See you later!

Когда мы выполняем вышеуказанный блок кода, происходит следующее:

  1. Оператор for внутри себя вызывает iter() для списка [«You», «are», «awesome!»]. Это приводит к получению итератора.
  2. Затем вызывается next() для итератора, и возвращаемое им значение присваивается переменной цикла, в данном случае word.
  3. После этого выполняется блок оператора, связанный с циклом for. В этом случае print(word).
  4. Шаги 2 и 3 повторяются до тех пор, пока next() не вызовет StopIteration.
  5. Как только next() вызывает StopIteration, управление переходит к предложению else, если оно присутствует, и выполняется блок операторов, связанных с else.

Примечание. Если в блоке кода, связанном с циклом for, встречается оператор break, то блок else пропускается.

Реализация логики цикла for с помощью оператора while

Мы могли бы реализовать вышеуказанную логику, используя оператор while следующим образом.

my_list = ["You", "are", "awesome!"]
list_iter = iter(my_list)
while True:
  try:
    word = next(list_iter)
    print(word)
  except StopIteration:
    print("See you later!")
    break

Цикл while ведет себя точно так же, как наш цикл for, и выдает следующий результат.

You
are
awesome!
See you later!

Разбор цикла for

В этом разделе мы разберем цикл for и пройдемся по инструкциям, которые интерпретатор исполняет при выполнении цикла for. Мы будем использовать модуль dis для разборки цикла for. Чтобы быть точным, мы будем использовать метод dis.dis, чтобы получить удобочитаемое представление дизассемблированного байт-кода.

Мы будем использовать тот же простой цикл for, который мы рассматривали до сих пор. Запишем следующий цикл for в файл for_loop.py.

for word in ["You", "are", "awesome!"]:
  print(word)
else:
  print("See you later!")

Теперь мы можем получить читаемую форму байт-кода, вызвав dis.dismethod. Запустим следующую команду в терминале.

$ python3 -m dis for_loop.py
  1           0 SETUP_LOOP              28 (to 30)
              2 LOAD_CONST               0 (('You', 'are', 'awesome!'))
              4 GET_ITER
        >>    6 FOR_ITER                12 (to 20)
              8 STORE_NAME               0 (word)

  2          10 LOAD_NAME                1 (print)
             12 LOAD_NAME                0 (word)
             14 CALL_FUNCTION            1
             16 POP_TOP
             18 JUMP_ABSOLUTE            6
        >>   20 POP_BLOCK

  4          22 LOAD_NAME                1 (print)
             24 LOAD_CONST               1 ('See you later!')
             26 CALL_FUNCTION            1
             28 POP_TOP
        >>   30 LOAD_CONST               2 (None)
             32 RETURN_VALUE

Каждый из столбцов в разобранном виде представляет следующее:

  1. Колонка 1: номер строки кода.
  2. Колонка 2: знак «>>», если инструкция является целью перехода.
  3. Колонка 3: смещение байт кода в байтах.
  4. Колонка 4: инструкция байт-кода.
  5. Колонка 5: аргументы инструкции. В скобках отображается более понятный для человека имя аргументов.

Теперь давайте шаг за шагом пройдемся по нашему разобранному байт-коду и попытаемся понять, что на самом деле происходит.
В этом описание термин TOS означает вершина стека (top of the stack)

  1. строка 1, for word in [“You”, “are”, “awesome!”]: переводится как:
    • 0 SETUP_LOOP 28 (to 30)
      • Этот оператор помещает блок для цикла for в стек. Блок занимает от этой инструкции до 28 байт, то есть до «30»
      • Это означает, что если в цикле for есть оператор break, управление переместится на «30» байт. Обратите внимание, блок else, будет пропущен если встретится оператор break.
    • 2 LOAD_CONST 0 ((‘You’, ‘are’, ‘awesome!’))
      • Затем список помещается на вершину стека (TOS).
    • 4 GET_ITER
      • Эта инструкция выполняет «TOS = iter (TOS)». Это означает, что итератор получается из списка, который на данный момент является TOS, а затем итератор переносится в TOS.
    • 6 FOR_ITER 12 (to 20)
      • Эта инструкция получает TOS, который на данный момент является нашим итератором, и вызывает для него метод next().
      • Если next() возвращает значение, оно помещается в стек, и будет выполнена следующая инструкция «8 STORE_NAME».
      • Как только функция next() указывает, что итератор исчерпан (т. к. сработал StopItered), TOS (а именно итератор) будет извлечен из стека, а счетчик байтового кода будет увеличен на 12. Это означает, что элемент управления перейдет к инструкция «20 POP_BLOCK».
    • 8 STORE_NAME 0 (word)
      • Эта инструкция преобразуется в word = TOS, то есть значение, возвращаемое функцией next(), будет присвоено переменной word.
  2. строка 2, print(word) переводится как:
    • 10 LOAD_NAME 1 (print)
      • Эта команда помещает команду print в стек.
    • 12 LOAD_NAME 0 (word)
      • Это команда перемещает аргумент print, то есть word в стек.
    • 14 CALL_FUNCTION 1
      • Это команда вызывает функцию с позиционными аргументами.
      • Аргументы, связанные с функцией, будут присутствовать в TOS, как мы видели в предыдущей инструкции. Все аргументы выталкиваются до тех пор, пока не получит вызываемый объект, то есть print.
      • Как только он получает вызываемый объект, он вызывается путем передачи ему всех аргументов.
      • Как только вызов выполнен, его возвращаемое значение будет передано в TOS. В текущий момент это будет None.
    • 16 POP_TOP
      • TOS, то есть возвращаемое значение из функции удаляется (выталкивается) из стека.
    • 18 JUMP_ABSOLUTE 6
      • Счетчик байт-кода теперь установлен на «6». Это означает, что следующая выполняемая инструкция будет «6 FOR_ITER». Вот так цикл проходит по элементам итератора.
      • Обратите внимание, что инструкция «6 FOR_ITER» заставит программу выйти из этого цикла и перейти к «20 POP_BLOCK», как только все элементы итератора будут исчерпаны.
    • 20 POP_BLOCK
      • POP_BLOCK приведет к удалению блока, установленного в «0 SETUP_LOOP», из стека блоков.
  3. Обратите внимание, что номер строки 3, т.е., else, не имеет каких-либо конкретных инструкций, связанных с этим. Управление программой естественным образом переходит к следующей инструкции, которая в основном состоит из операторов, связанных с else.
  4. строка 4, “print(“See you later!”)” переводится как:
    • 22 LOAD_NAME 1 (print)
      • Вызываемый объект, связанный с print, помещается в стек.
    • 24 LOAD_CONST 1 (‘See you later!’)
      • Аргументы для вызываемого объекта помещаются в стек.
    • 26 CALL_FUNCTION 1
      • Аргументы для print и команда print извлекаются из стека. Затем выполняется вызываемая функция, и ее возвращаемое значение передается в TOS.
    • 28 POP_TOP
      • TOS, то есть возвращаемое значение функции (в данном случае None) удаляется из стека.
  5. Следующие две инструкции в основном загружают возвращаемое значение нашего скрипта (None) в стек и возвращают его.
    • 30 LOAD_CONST 2 (None)
    • 32 RETURN_VALUE

Вув! Итак, мы закончили с разборкой инструкций для цикла for. Я надеюсь, что это поможет немного лучше понять работу цикла for.

Заключение

В этом посте мы рассмотрели следующее:

  1. Как написать цикл for в Python?
  2. Как использовать else, связанное с циклом for?
  3. Что такое итераторы и итерируемые объекты?
  4. Что такое протокол итератора?
  5. Как создать итератор и итерируемый объект?
  6. Как работает цикл for?
  7. Как используя цикл while имитировать цикл for?
  8. Как разобрать цикл for с помощью модуля dis и увидеть понятные человеку инструкции, выполняемые интерпретатором Python? Как читать и понимать разобранные инструкции?

Оригинальная статья Shyama Sankar Understanding for-loops in Python

Была ли вам полезна эта статья?

Понравилась статья? Поделить с друзьями:
  • For word in list python
  • For word games перевод
  • For word document example
  • For while excel миф
  • For what this word i love you