Effective Python Learning Memorandum Day 4 [4/100]

Introduction

The other day I learned about 100 Days Of Code, which was popular on Twitter for a while. The purpose of this article is to keep a record and output how much I, as a beginner, can grow through 100 days of study. I think there are many mistakes and difficult to read. I would appreciate it if you could point out!

Teaching materials to be learned this time

Today's progress

--Progress: Pages 38-48 ――I will write down what I often forget or didn't know about what I learned today.

Respect for certainty when using iterators for arguments

--If iterates with an iterator or generator and the StopIteration exception has already occurred, iterating again will not produce any results.

numbers = [1, 2, 3, 4, 5]

def iter_square(numbers):
    for number in numbers:
        yield number ** 2

iter = iter_square(numbers)
for x in iter:
    print(x)
#No output for the second for statement due to a StopIteration exception
for x in iter:
    print(x)

Output result

1
4
9
16
25

Iterating over an iterator that has already run out is very confusing as it does not cause any errors. To solve this problem, I run the input iterator until it's explicitly exhausted and copy it to the full content list. The list can be iterated over and over again, eliminating this confusion.

numbers = [1, 2, 3, 4, 5]

def iter_square(numbers):
    for number in numbers:
        yield number ** 2

iter = iter_square(numbers)
iter_list = list(iter)
for x in iter_list:
    print(x)
for x in iter_list:
    print(x)

Output result

1
4
9
16
25
1
4
9
16
25

However, since it uses a list, it may crash if the contents of the copy of the input iterator become large. To avoid this, define a new container class that implements the iterator protocol.

numbers = [1, 2, 3, 4, 5]

class SampleClass(object):
    def __init__(self, numbers):
        self.numbers = numbers

    def __iter__(self):
        for number in self.numbers
            yield number

def func_square(numbers):
    result = []
    for value in numbers:
        square_value = value ** 2
        result.append(square_value)
    return result

num = SampleClass(numbers)
result = func_square(num)
print(result)

Use variable-length position arguments to make it look neat

--Star arguments (* args) can be used to keep function calls nesting and reduce visual noise. --The function can accept a variable number of positional arguments by using * args in the def statement. -* Operators can be used in functions to use elements from sequences as positional arguments -* When using the operator with a generator, the program may run out of memory and crash. --Adding a new position parameter to a function that accepts * args can create bugs that are difficult to find.

For example, when logging debug information, if you have a fixed number of arguments, you need a function that takes a message and a list of values.

def log(message, values):
    if not values:
        print(message)
    else:
        values_str = ', '.join(str(x) for x in values)
        print('%s: %s' % (message, values_str))

log('MY numbers are', [1, 2])
log('Hi there', [])

It's annoying to have to pass an empty list even when there is no value. In Python, it can be made optional by adding * to the name of the last positional argument.

def log(message, *values):
    if not values:
        print(message)
    else:
        values_str = ', '.join(str(x) for x in values)
        print('%s: %s' % (message, values_str))

log('MY numbers are', [1, 2])
log('Hi there')

If you already have a list and want to call a variadic function like log, you can call it using the * operator.

log('HELLO', *list)
# *If you do not add, the list will be output as it is.
log('HELLO', list)

Output result

HELLO: 1, 2, 3
HELLO: [1, 2, 3]

There are two problems with variable-length positional arguments.

  1. Always converted to a tuple before being passed to a function --If the caller uses the * operator in the generator, it will iterate until it runs out, which can consume a lot of memory and crash the program.
  2. You cannot add new positional arguments to a function without modifying all callers.

Give optional behavior to keyword arguments

--Function arguments can be specified by position or keyword --Keyword arguments clarify the purpose of each argument when the positional argument alone is confusing. --Keyword arguments with default values ​​make it easy to add new behavior to a function, even if it has already been called by others. --Optional keyword arguments should always be passed by keyword, not position

Recommended Posts

Effective Python Learning Memorandum Day 15 [15/100]
Effective Python Learning Memorandum Day 6 [6/100]
Effective Python Learning Memorandum Day 12 [12/100]
Effective Python Learning Memorandum Day 9 [9/100]
Effective Python Learning Memorandum Day 8 [8/100]
Effective Python Learning Memorandum Day 14 [14/100]
Effective Python Learning Memorandum Day 1 [1/100]
Effective Python Learning Memorandum Day 13 [13/100]
Effective Python Learning Memorandum Day 3 [3/100]
Effective Python Learning Memorandum Day 5 [5/100]
Effective Python Learning Memorandum Day 4 [4/100]
Effective Python Learning Memorandum Day 7 [7/100]
Effective Python Learning Memorandum Day 2 [2/100]
Python learning day 4
Python Memorandum 2
Python memorandum
python learning
python memorandum
python memorandum
Python day 1
Python memorandum
python memorandum
Python memorandum
Python basics memorandum
[Python] Learning Note 1
Python pathlib memorandum
Python memorandum (algorithm)
python learning output
Deep Learning Memorandum
Python Deep Learning
Python learning (supplement)
Deep learning × Python
Python memorandum [links]
python learning notes
Python study day 1
Machine learning starting with Python Personal memorandum Part2
Machine learning starting with Python Personal memorandum Part1
Python memorandum numbering variables
Python class (Python learning memo ⑦)
Learning Python with ChemTHEATER 03
"Object-oriented" learning with python
Python module (Python learning memo ④)
Reinforcement learning 1 Python installation
Learning Python with ChemTHEATER 05-1
Python: Deep Learning Practices
Python ~ Grammar speed learning ~
python memorandum (sequential update)
Python: Unsupervised Learning: Basics
Learning record 4 (8th day)
[1day1lang AdventCalender] day4 Python
Learning record 3 (7th day)
Learning record 5 (9th day)
Learning record 6 (10th day)
Python memorandum (personal bookmark)
Programming learning record day 2
Learning record 8 (12th day)
Learning record 1 (4th day)
Learning record 7 (11th day)
Private Python learning procedure
Python basic memorandum part 2
Learning Python with ChemTHEATER 01