「大人の教養・知識・気付き」を伸ばすブログ

一流の大人(ビジネスマン、政治家、リーダー…)として知っておきたい、教養・社会動向を意外なところから取り上げ学ぶことで“気付く力”を伸ばすブログです。データ分析・語学に力点を置いています。 →現在、コンサルタントの雛になるべく、少しずつ勉強中です(※2024年1月21日改訂)。

MENU

Pythonをゆっくりていねいに学ぶ(その07/X)

 Pythonを真面目にゆっくり学ぶべく

を参考に学んでいきます*1

4. Pyの皮:コード構造

4.5 内包表記

 一つ以上のイテレータから\mathrm{Python}データ構造をコンパクトに作成できる形式を内包表記という。

4.5.1 リスト内包表記
########################
### リストの内包表記 ###
########################

# [expression for item in iterable]
# 基本的な書き方
number_list1 = [number for number in range(1,6)]
number_list2 = [number*2 for number in range(1,6)]

print(number_list1)
print(number_list2)

# 条件を追記
a_list = [number for number in range(1,6) if number % 2 ==1]

print(a_list)

# 複数のfor文を記入
rows = range(1,4); cols = range(1,3)
cells = [(row, col) for row in rows for col in cols]
print(cells)
4.5.2 辞書の内包表記
######################
### 辞書の内包表記 ###
######################

# {key_item: value_item for item in iterable}
word = 'letter'
letter_counts = {letter:word.count(letter) for letter in word}
print(letter_counts)
4.5.3 集合内包表記
####################
### 集合内包表記 ###
####################

# {item for item in iterable}
a_set = {number for number in range(1,6) if number % 3 == 1}
print(a_set)
4.5.4 ジェネレータ内包表記
##########################################################
### タプル内包表記⇒はなく、ジェネレータという型になる ###
##########################################################

number_thing = (number for number in range(1,6))

type(number_thing)

4.6 関数

 コードの再利用に有用なのに関数がある。プログラマは関数に対して、

  • 関数の定義
  • 関数の呼び出し

ができる。
 \mathrm{Python}関数の定義には、\mathrm{def}と入力し、関数名を書き、関数に対する入力引数を括弧で囲んで書いたうえで最後にコロンを書く。

##################
### 関数の定義 ###
##################

# 以下のような形式で出力
def make_response(a):
    return True

make_response(False)

4.7 特殊な引数

4.7.1 None

 \mathrm{Python}には特殊な値として\mathrm{None}が存在する。\mathrm{None}は値が「存在しない」ことを意味し、\mathrm{Bool}値の\mathrm{False}とは明確に異なる値である。\mathrm{None}\mathrm{is}演算子で区別する。

thing = None

if thing is None:
    print("It's nothing.")
else:
    print("It's something.")
4.7.2 引数の与え方

 \mathrm{Python}は、関数に渡された引数の処理の面で他の言語よりも柔軟である。最もよく知られた引数のタイプは先頭から順に対応する位置の仮引数にコピーされる位置引数である。
 他方で明示的にどの変数にどの値を代入するかを明示的に行うキーワード引数という方法もある。位置引数とキーワード引数は併存しても問題が無い。またデフォルト引数値を設定することもできる。デフォルト引数値は関数を定義した際に代入される*2

# 位置引数
## 渡す値の順番が出力に影響する
def menu(wine, entree, dessert):
    print({'wine':wine, 'entree':entree, 'dessert':dessert})
    
menu('red','beef', 'ice cream')
menu('beef', 'ice cream', 'red')

print(' ')
print('*****************')
print(' ')

# キーワード引数
## 値を渡す対象となる引数と値とを明記する
menu(wine = 'red',entree = 'beef', dessert = 'ice cream')
menu(entree = 'beef', dessert = 'ice cream',wine = 'red')
menu('red',entree = 'beef', dessert = 'ice cream') # 位置引数とキーワード引数は併存可能

print(' ')
print('*****************')
print(' ')
# デフォルト引数
## 仮引数にはデフォルト値を指定できる
## デフォルト値を与えた引数は値を指定しなければデフォルト値が勝手に代入される
def menu2(wine, entree, dessert = 'pudding'):
    print({'wine':wine, 'entree':entree, 'dessert':dessert})

menu2(wine = 'blanc', entree = 'poisson')    
4.7.3 *による位置引数のタプル化

 \mathrm{Python}にはポインタ(*)は無い。しかし\mathrm{Python}の仮引数の一部として*を用いることができ、これは可変個の位置引数をタプルにまとめてセットすることになる。

#############################
### *を用いた仮引数の設定 ###
#############################


def print_args(*args):
    print('Positional argument tuple:',args)
    
print_args() # 引数に指定が無いと何も入らない

print_args(3,2,1,'wait!') # 渡した位置引数はargsタプルとして表示される 
4.7.4 **によるキーワード引数の辞書化

 ふたつのアスタリスク(**)を用いると、キーワード引数を1つの辞書にまとめることができる。引数の名前が辞書のキー、引数の値は辞書の値になる。

########################################
### **を用いたキーワード引数の辞書化 ###
########################################

def print_kw_args(**kwargs):
    print('Keyword arguments:', kwargs)

print_kw_args(wine = 'red', entree = 'fish', dessert = 'pudding')

4.7.5 docstring

 関数本体の先頭に文字列を組み込んで関数定義にドキュメントを付けることができる。これを関数の\mathrm{docstring}という。

#################
### docstring ###
#################

def echo(everything):
    '''
    与えられた引数を返す
    '''
    print(everything)

print(echo.__doc__) # __doc__は関数内の変数としてのdocstring
4.7.6 オブジェクトとしての関数

 \mathrm{Python}では関数も1つのオブジェクトである。そのため変数に関数を代入した利、他の関数の引数に関数を与えたり、関数からの戻り値に関数を返したりできる。

################################
### オブジェクトとしての関数 ###
################################

# 適当な関数
def answer():
    print(42)

# 引数として関数オブジェクトを取る関数
def run_something(func):
    func()

run_something(answer)


##########

def add_args(arg1,arg2):
    print(arg1 + arg2)

def run_something_with_args(func,arg1,arg2):
    return func(arg1, arg2)

run_something_with_args(func = add_args, arg1 = 3, arg2 = 2) # 結果的にadd_args(arg1,arg2)
4.7.7 関数内関数

 関数内で関数を定義でき、ループやコードの重複を避けるのに有用である。

##########################
### 関数内で関数を定義 ###
##########################

def outer(a,b):
    def inner(c, d):
        return c + d
    return inner(a, b)

outer(4, 7)

 関数内関数はクロージャー(他の関数によって動的に生成される関数)である。

  • \mathrm{inner2}()は引数を要求せず外側の関数に対する\mathrm{saying}引数を直接用いる。
  • \mathrm{knights2}()\mathrm{inner2}を呼び出すのではなく、その関数名を返す
def knights(saying):
    def inner(quote):
        return "We are the knights who say: '%s'" % quote
    return inner(saying)

knights('Hi!')

def knights2(saying):
    def inner2():
        return "We are the knights who say: '%s'" % saying
    return inner2

knights2('Hi!')

*1:第2版が出ているものの初版しか持っていないのでこちらで。

*2:そのためリストや辞書などのミュータブルなデータ型をデフォルト引数として使用して想定しない動作をしないようにすること。

プライバシーポリシー お問い合わせ