LoginSignup
0
0

Python備忘録3(関数)

Last updated at Posted at 2023-08-21

関数

def1

def1.py
def print_hello():
    print('Hello')

print_hello()
console
Hello

def2

def2.py
def print_hello(name):
    print(f'Hello {name}!')

print_hello('towamz')
console
Hello towamz!
  • 引数を設定できる。

def3

def3.py
def print_hello(name='there'):
    print(f'Hello {name}!')

print_hello()
print_hello('towamz')
console
Hello there!
Hello towamz!
  • 引数にデフォルト値を設定できる

def4

def4.py
def print_hello(*names):
    for name in names:
        print(f'Hello {name}!')

print_hello()
print_hello('towamz','jo')
console
Hello towamz!
Hello jo!
  • 引数に*をつけると、タプルで引数を受け取る。引数の数は可変。

def5

def5.py
def print_cat(**catInfo):
    for k in catInfo:
        print(f'{k}={catInfo.get(k)}')

print_cat(type='cat',fur='white',gender='male')
console
type=cat
fur=white
gender=male
  • 引数に**をつけると、ディクショナリで引数を受け取る。引数の数は可変。

def6

def6.py
def functionSample(arg1,*arg2,**arg3):
    print(f'{arg1=},{arg2=},{arg3=}')

functionSample(1,2,3,4,5,name='towamz',age=20)
console
arg1=1,arg2=(2, 3, 4, 5),arg3={'name': 'towamz', 'age': 20}
  • 通常の引数。タプル型可変引数。ディクショナリ型可変引数を同時に指定できる。

inner関数

def-inner.py
# 関数内に関数を書ける(we can put a function inside a function)
def funcOut():
    def funcIn():
        print('innerFunction')
    funcIn()

funcOut()
# インナー関数は直接呼び出せない(Inner functions cannot be called directly)
funcIn()
console
innerFunction
Traceback (most recent call last):
  File "def-inner.py", line 10, in <module>
    funcIn()
NameError: name 'funcIn' is not defined

scope

local scope

localScope.py
def checkScope():
    pet = 'cat'
    print(f'関数内:{pet},{id(pet)}')

pet = 'dog'
checkScope()
print(f'関数外:{pet},{id(pet)}')
console
関数内:cat,139817805712752
関数外:dog,139817805713200

global scope

globalScope.py
def checkScope():
    global pet 
    pet = 'cat'
    print(f'関数内:{pet},{id(pet)}')

# pet = 'dog'
checkScope()
print(f'関数外:{pet},{id(pet)}')
console
関数内:cat,140466196876656
関数外:cat,140466196876656

nonlocal scope

nonlocalScope.py
def func1():
    Val = 'func1'
    def func2():
        nonlocal Val
        Val = 'func2'
        def func3():
            nonlocal Val
            Val = 'func3'
            print(f'{Val = },{id(Val) = }')

        func3()
        print(f'{Val = },{id(Val) = }')
    func2()
    print(f'{Val = },{id(Val) = }')
func1()

console
Val = 'func3',id(Val) = 139659068084016
Val = 'func3',id(Val) = 139659068084016
Val = 'func3',id(Val) = 139659068084016
nonlocalScope2.py
# nonlocalを宣言しないと関数ごとに違う変数となる
def func1():
    Val = 'func1'
    def func2():
        Val = 'func2'
        def func3():
            Val = 'func3'
            print(f'{Val = },{id(Val) = }')

        func3()
        print(f'{Val = },{id(Val) = }')
    func2()
    print(f'{Val = },{id(Val) = }')
func1()
console
Val = 'func3',id(Val) = 139942491885360
Val = 'func2',id(Val) = 139942491885104
Val = 'func1',id(Val) = 139942491838384

ジェネレーター関数

ジェネレーター関数1

generator1.py
def generatorFunc():
    n = 100

    for _ in range(10):
        yield n
        n += 1

gen = generatorFunc()

for _ in range(11):
    # yieldで返した値を受け取る
    n = next(gen)
    print(f'{n=}')
console
n=100
n=101
n=102
n=103
n=104
n=105
n=106
n=107
n=108
n=109
Traceback (most recent call last):
  File "generator1.py", line 12, in <module>
    n = next(gen)
StopIteration
  • yieldの引数を返しそこで処理が止まる。nextでyieldの次から処理を再開する。
  • 関数の最後に達しyieldが実行できない場合は[StopIteration]例外が発生する。

ジェネレーター関数2

generator2.py
def generatorFunc():
    n = 0
    while True:
        # send()の値を受け取る
        sendVal = yield n

        # next()を実行したときはyieldは[None]を返す
        if sendVal == None:
            n += 1
        else:
            n = sendVal

gen = generatorFunc()

for _ in range(10):
    n = next(gen)
    print(f'{n=}')

n = gen.send(150)
print(f'send{n=}')

for _ in range(10):
    n = next(gen)
    print(f'{n=}')

# generator関数を終了する
gen.close()

# generator関数を終了した後nextを実行するとStopIteration例外が発生する
n = next(gen)
console
n=0
n=1
n=2
n=3
n=4
n=5
n=6
n=7
n=8
n=9
sendn=150
n=151
n=152
n=153
n=154
n=155
n=156
n=157
n=158
n=159
n=160
Traceback (most recent call last):
  File "generator2.py", line 31, in <module>
    n = next(gen)
StopIteration

ジェネレーター関数3

generator3.py
def generatorFunc():
    n = 100

    for _ in range(10):
        yield n
        n += 1

gen = generatorFunc()

print(f'{next(gen)}')

gen.throw(Exception('unexpected Errorです'))
console
100
Traceback (most recent call last):
  File "generator3.py", line 12, in <module>
    gen.throw(Exception('unexpected Errorです'))
  File "generator3.py", line 5, in generatorFunc
    yield n
Exception: unexpected Errorです

サブジェネレーター関数

sub-generator.py
def generator3rd():
    for i in range(100,105):
        yield "g3-y" + str(i)
    return "g3-r"

def generator2nd():
    for i in range(10,15):
        yield "g2-y" + str(i)
    g2r = yield from generator3rd()
    print("g2r:",g2r)
    return "g2-r"

def generator():
    yield "g-y"
    gr = yield from generator2nd()
    print("gr:",gr)
    return "g-r"


gen = generator()

for _ in range(20):
    print(next(gen))
console
g-y
g2-y10
g2-y11
g2-y12
g2-y13
g2-y14
g3-y100
g3-y101
g3-y102
g3-y103
g3-y104
g2r: g3-r
gr: g2-r
Traceback (most recent call last):
  File "sub-generator.py", line 27, in <module>
    print(next(gen))
StopIteration: g-r

高階関数

higherOrderFunction.py
def funcSub1(name):
    print(f'Hi! {name}')

def funcSub2(name):
    print(f'Bye! {name}')

def funcRtn(msg):
    print(f'{msg}')

def funcRoot(fn):
    fn('towam')
    return funcRtn


var1 = funcRoot(funcSub1)
var1('こんにちは')

var2 = funcRoot(funcSub2)
var2('さようなら')

console
Hi! towam
こんにちは
Bye! towam
さようなら
  • 高階関数は、関数を引数・戻り値にする関数のこと

lambda

三項演算子

ternaryOperator.py
vals = '0','a'

for i in vals:
    judge = "数字です" if i.isdigit() else "数字ではありません"
    print(judge)
console
数字です
数字ではありません
  • [Trueの時に返す値] if [条件式] else [falseの時に返す値]

lambda1

lambda1.py
l1 = lambda : print('Hello World')
l1()
console
Hello World
  • lambdaは、関数を1行で定義し関数名を付けない

lambda2

lambda2.py
l2 = lambda x: print(f'{x}を受け取りました')
l2('towamz')
console
towamzを受け取りました
  • lambdaは、引数を受け取ることができる

lambda3

lambda3.py
l3 = lambda x,y,z: x if all((x>y,x>z)) else y if y>z else z
print(l3(1,5,10))
print(l3(15,5,10))
print(l3(15,20,10))
console
10
15
20
  • lambdaは、条件分岐できる

再帰関数

fibonacci number

recursive-fibonacci.py
def getfibonacciNumber(n):
    global result

    # listの要素数が不足している場合は要素を追加する。値は計算未実行の-1を代入。
    if len(result) <= n:
        result += [-1] * (n - len(result) + 1)
        print('afterExtentionExec:',result)

    # 計算未実行のときは計算する
    if result[n] == -1:
        print('calculation exec:',n)
        result[n] = getfibonacciNumber(n - 1) + getfibonacciNumber(n - 2)

    return result[n]
 


result = [0,1]

print('--')
i = 10
print(i,len(result),result)
print(getfibonacciNumber(i))
print(i,len(result),result)

print('--')
i = 15
print(i,len(result),result)
print(getfibonacciNumber(i))
print(i,len(result),result)

print('--')
i = 5
print(i,len(result),result)
print(getfibonacciNumber(i))
print(i,len(result),result)
console
--
10 2 [0, 1]
afterExtentionExec: [0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
calculation exec: 10
calculation exec: 9
calculation exec: 8
calculation exec: 7
calculation exec: 6
calculation exec: 5
calculation exec: 4
calculation exec: 3
calculation exec: 2
55
10 11 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
--
15 11 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
afterExtentionExec: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, -1, -1, -1, -1, -1]
calculation exec: 15
calculation exec: 14
calculation exec: 13
calculation exec: 12
calculation exec: 11
610
15 16 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
--
5 16 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
5
5 16 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

デコレーター関数

decoretor.py
def decoretorFunction(argumentFunction):
    def wrapper(*args, **kwargs):
        print('共通の処理開始')
        argumentFunction(*args, **kwargs)
        print('共通の処理終了')
    return wrapper


@decoretorFunction
def decoretorSubfunc1(*args, **kwargs):
    print('Subfunc1を開始')
    for i in range(args[0],args[1]):
        print(i)
    print('Subfunc1を終了')

@decoretorFunction
def decoretorSubfunc2(*args, **kwargs):
    print('Subfunc2を開始')
    for i in range(args[0],args[1]):
        print(i ** 2)
    print('Subfunc2を終了')


decoretorSubfunc1(10,20)
print('-' * 10)
decoretorSubfunc2(10,20)
console
共通の処理開始
Subfunc1を開始
10
11
12
13
14
15
16
17
18
19
Subfunc1を終了
共通の処理終了
----------
共通の処理開始
Subfunc2を開始
100
121
144
169
196
225
256
289
324
361
Subfunc2を終了
共通の処理終了

map関数

map1

map1.py
decimalNumber = [1,2,4,8,16,32]

decimalNumberShitf = map(lambda x:x * 2, decimalNumber)

for x,y in zip(decimalNumber,decimalNumberShitf): 
    print(x,y)

print(decimalNumberShitf)
console
1 2
2 4
4 8
8 16
16 32
32 64
<map object at 0x7f2020957ee0>

map2

map2.py
def isDivisible(x,y):
    if x % y == 0:
        return True
    else:
        return False

results = map(isDivisible, range(10,15), [3,2,3,5,7])
for x in results:
    print(x)
console
False
False
True
False
True

# 参考
False #10/3は割り切れない
False #11/2は割り切れない
True   #12/3は割り切れる
False  #13/5は割り切れない
True   #14/7は割り切れる

zip関数

zip1

zip.py
list1 = [i for i in range(0,5)]
list2 = [i for i in range(10,15)]

print(list1,list2)

list3 =[i + j for i,j in zip(list1,list2)]
print(list3)
console
[0, 1, 2, 3, 4] [10, 11, 12, 13, 14]
[10, 12, 14, 16, 18]

.py

console

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0