About Python for loops

The goal of this story

for loop

for_loop.py


for i in [0, 1, 2, 3, 4]:
    print(i)

When you run

% python for_loop.py
0
1
2
3
4

for i inI want to know how the thing behind is used. (In the case of the above example, it seems that the elements of ``` [0, 1, 2, 3, 4]` `` are extracted in order.)

Try putting in a nice object

Let's see how it is hit with reference to the runtime error

duck.py


class Duck(object):
    pass


if __name__ == '__main__':
    for i in Duck():
        print(i)

When I run it, I get angry if it is not iterable

% python duck.py
Traceback (most recent call last):
  File "duck.py", line 6, in <module>
    for i in Duck():
TypeError: 'Duck' object is not iterable

Try implementing iterable

I was told to implement it, so I will implement it. But just return an empty object

duck.py


class DuckIter(object):
    def __init__(self):
        pass


class Duck(object):
    def __iter__(self):
        return DuckIter()


if __name__ == '__main__':
    for i in Duck():
        print(i)

The error has changed (one step forward!)

% python duck.py
Traceback (most recent call last):
  File "duck.py", line 12, in <module>
    for i in Duck():
TypeError: iter() returned non-iterator of type 'DuckIter'

Try implementing iterator

Try to squeal three times.

duck.py


class DuckIter(object):
    def __init__(self):
        self._count = 3

    def next(self):
        if self._count > 0:
            self._count -= 1
            return "quack"
        raise StopIteration()


class Duck(object):
    def __iter__(self):
        return DuckIter()


if __name__ == '__main__':
    for i in Duck():
        print(i)

No more errors when run

% python duck.py
quack
quack
quack

The duck rang!

Duck typing

If it walks like a duck and quacks like a duck, it must be a duck https://ja.wikipedia.org/wiki/ダック・タイピング

The object itself determines what the object can do (Regardless of what inheritance they have)

In the case of the previous example

This allowed us to turn the for loop:

for i in Duck():
    print(i)

This notation is roughly the same as below

iter = Duck().__iter__()
while True:
    try:
        i = iter.next()
        print(i)
    except StopIteration:
        break

In other words, the processing flow of the for loop is

  1. Get iterator
  2. Call the iterator's next () method
  3. If it is not StopIteration, perform "Processing in the loop" and go to 2. again.

A little practice

Let's create an object with iterator in reverse order from list

>>> lst = [0, 1, 2, 3, 4]
>>> rev = RevList(lst)
>>> for r in rev:
...     print(r)
...
4
3
2
1
0

Tip:

Answer 1

class RevListIter(object):
    def __init__(self, lst):
        self._orig = lst
        self._i = len(lst)

    def next(self):
        if self._i > 0:
            self._i -= 1
            return self._orig[self._i]
        raise StopIteration()


class RevList(object):
    def __init__(self, lst):
        self._orig = lst

    def __iter__(self):
        return RevListIter(self._orig)


if __name__ == '__main__':
    lst = [0, 1, 2, 3, 4]
    rev = RevList(lst)
    for r in rev:
        print(r)

Answer 2

class RevList(object):
    def __init__(self, lst):
        self._orig = lst

    def __iter__(self):
        return self._orig[::-1].__iter__()


if __name__ == '__main__':
    lst = [0, 1, 2, 3, 4]
    rev = RevList(lst)
    for r in rev:
        print(r)

Difference between the two answers

List comprehension and generator representation

Another practice

Let's create an iterator that squares each element of a list of integers

>>> lst = [0, 1, 2, 3, 4]
>>>for i in something(lst):
...     print(i)
...
0
1
4
9
16

Two sample answers

>>> lst = [0, 1, 2, 3, 4]
>>> for i in [x*x for x in lst]:
...     print(i)
...
0
1
4
9
16
>>> for i in (x*x for x in lst):
...     print(i)
...
0
1
4
9
16

Both are solutions. Let's see the difference between the two.

List comprehension

notation

[f(x) for x in lst]

Sample code

list_comprehension.py


def f(x):
    print("%d*%d" % (x, x))
    return x*x

if __name__ == '__main__':
    lst = [0, 1, 2, 3, 4]
    x = [f(x) for x in lst]
    print(type(x))
    for i in x:
        print(i)

Execution result

% python list_comprehension.py
0*0
1*1
2*2
3*3
4*4
<type 'list'>
0
1
4
9
16

Generator representation

notation

(f(x) for x in lst)

Sample code

generator_expression.py


def f(x):
    print("%d*%d" % (x, x))
    return x*x

if __name__ == '__main__':
    lst = [0, 1, 2, 3, 4]
    x = (f(x) for x in lst)
    print(type(x))
    for i in x:
        print(i)

Execution result

% python generator_expression.py
<type 'generator'>
0*0
0
1*1
1
2*2
4
3*3
9
4*4
16

Summary

Recommended Posts

About Python for loops
About Python, for ~ (range)
About Fabric's support for Python 3
About "for _ in range ():" in python
About python slices
python [for myself]
About python comprehension
About Python tqdm.
About python yield
About python, class
About python inheritance
About python, range ()
About python decorators
About python reference
About Python decorators
[Python] About multi-process
Summary about Python scraping
About function arguments (python)
Python basics ② for statement
[Python] Memo about functions
Play with Lambda layer (python) for about 5 minutes
Summary about Python3 + OpenCV3
python textbook for beginners
About pgbench for MySQL
About Python3 character code
Refactoring tools for Python
[Python] Memo about errors
About Python development environment
Python: About function arguments
Python, about exception handling
python for android Toolchain
About Python Pyramid traversal
About polymorphism for nesting
About Python3 ... (Ellipsis object)
[Python] Chapter 01-01 About Python (First Python)
[Python] About standard input
About __all__ in python
[Python] Learn about asynchronous programming and event loops
OpenCV for Python beginners
Install Python (for Windows)
[Python] for statement error
About Python external module import <For super beginners>
Python environment for projects
Write about building a Python environment for writing Qiita Qiita
About creating and modifying custom themes for Python IDLE
[Python of Hikari-] Chapter 05-05 Control syntax (for statement-multiple loops-)
python memo (for myself): About the development environment virtualenv
[Python] Find out about pip
Python memo (for myself): Array
Python list, for statement, dictionary
Python for Data Analysis Chapter 4
Modern Python for intermediate users
Learning flow for Python beginners
Python 3.6 installation procedure [for Windows]
About python objects and classes
About Python variables and objects
BigQuery integration for Python users
Python learning plan for AI learning
About the Python module venv
Set Up for Mac (Python)
Think about architecture in python