2013年5月15日水曜日

開発環境

『初めてのPython 第3版』(Mark Lutz 著、夏目 大 訳、オライリー・ジャパン、2009年、ISBN978-4-87311-393-7)のIV部(関数)の第17章(関数に関する高度なテクニック)の練習問題を解いてみる。

その他参考書籍

1, 2, 3, 4, 5, 6, 7.

コード(BBEdit)

sample.py

#!/usr/bin/env python3.3
#-*- coding: utf-8 -*-

# リスト内包表記
# 角括弧はリスト
n = 10**6
l = [x**2 for x in range(n)]

# 丸括弧はジェネレータ
g = (x**2 for x in range(n))

# リストとジェネレータの違いは、リストが一度に作られるのに対し、ジェネレータは
# 反復処理の中でその都度要素を返す(作成済のリストの方が反復処理は速い、
# ジェネレータの方がメモリの節約になる)
import time

start = time.time()
for x in l: pass
print("リスト: {0}秒".format(time.time() - start))

start = time.time()
for x in g: pass
print("ジェネレータ: {0}秒".format(time.time() - start))

# ジェネレータはイテレータプロトコルをサポートするオブジェクト

# yieldステートメントがあると、ジェネレータ関数は呼び出しでジェネレータオブジェクト
# を返す。実際に使ってみる
def g():
    for x in range(10):
        yield x

print("yield")
for x in g():
    print(x, end=" ")
print()

# returnとの違いを確認
def f():
    for x in range(10):
        return x
print("return")
print(f())

# *(タプル)や**(キーワード引数)を使えば、引数を確定せずに関数呼び出しのコードを書ける
def f(*args):
    print(args)

def g(**kargs):
    print(kargs)

# 混在もできる
def h(a, b, *args, **kargs):
    print(a, b)
    print(args)
    print(kargs)

f(1,2,3,4,5)
g(a=1,b=2)
h(10, 20, 30, 40, 50, k1=1, k2=2)

# map関数は各要素に関数を適用する。リスト内包表記では関数という制限は無く、式であればいい
a = [x * x for x in range(10)]
b = map(lambda x: x*x, range(10))
for x in a:
    print(x, end=" ")
print()
for x in b:
    print(x, end=" ")
print()

# リストは式であればいいので次の書き方も可能
c = [x*x for x in range(10)]
print(c)

# ifも使える
d = [x*x for x in range(10) if x % 2 == 0]
print(d)

# lambdaもdefも関数をを作成する点は共通。lambdaは式なので、式が使える場所なら使える
# けどdefではそうはいかない。lambdaは引数を何らかの処理をするのにブロックを使えない
# 同じ機能を持つ関数オブジェクトをlambdaとdefで作成
f = lambda x: x + 10
def g(x):
    return x + 10
print(f(5), g(5))

# 関数を値とするディクショナリを作成
# lambdaの場合
d1 = {'a': lambda: 10, 'b':lambda: 20}
# defを使った場合は関数を定義してからディクショナリを作成しなければならない
d2 = {}
def f():
    return 10
d2['a'] = f
def f():
    return 20
d2['b'] = f
print(d1['a'](), d2['b'](), sep=", ")

入出力結果(Terminal)

$ ./sample.py
リスト: 0.054656028747558594秒
ジェネレータ: 0.8610618114471436秒
yield
0 1 2 3 4 5 6 7 8 9 
return
0
(1, 2, 3, 4, 5)
{'a': 1, 'b': 2}
10 20
(30, 40, 50)
{'k1': 1, 'k2': 2}
0 1 4 9 16 25 36 49 64 81 
0 1 4 9 16 25 36 49 64 81 
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[0, 4, 16, 36, 64]
15 15
10, 20
$

0 コメント:

コメントを投稿