シェルスクリプトマガジン

Pythonあれこれ(Vol.73掲載)

著者:飯尾 淳

本連載では「Pythonを昔から使っているものの、それほど使いこなしてはいない」という筆者が、いろいろな日常業務をPythonで処理することで、立派な「蛇使い」に育つことを目指します。その過程を温かく見守ってください。皆さんと共に勉強していきましょう。第3回は、Pythonの言語機能である「ジェネレータ」に親しむための活用例を紹介します。

シェルスクリプトマガジン Vol.73は以下のリンク先でご購入できます。

図2 「jugem.txt」の内容を行単位で反転して表示するPythonコード

#!/usr/bin/env python
  
def readJugemu():
  with open('jugemu.txt', 'r') as f:
    return f.readlines()

lines = readJugemu()
for l in lines:
  print(l.rstrip()[::-1])

図5 lines変数を使わないコード例

#!/usr/bin/env python
  
def readJugemu():
  with open('jugemu.txt', 'r') as f:
    return f.readlines()

for l in readJugemu():
  print(l.rstrip()[::-1])

図6 ジェネレータを使用したPythonコード「reverse2.py」

#!/usr/bin/env python
  
def readJugemu():
  with open('jugemu.txt', 'r') as f:
    for line in f:
      yield line

for l in readJugemu():
  print(l.rstrip()[::-1])

図7 関数readJugemu()が返すデータの種類を調べるPythonコード「test.py」

#!/usr/bin/env python
  
def readJugemu():
  with open('jugemu.txt', 'r') as f:
    return f.readlines()

lines = readJugemu()
print(type(lines))

図8 ジェネレータ関数readJugemu()が返すデータの種類を調べるPythonコード「test2.py」

#!/usr/bin/env python
  
def readJugemu():
  with open('jugemu.txt', 'r') as f:
    for line in f:
      yield line

lines = readJugemu()
print(type(lines))

図9 ジェネレータ関数readJugemu()をfor文で使用するPythonコード「reverse3.py」

#!/usr/bin/env python
  
def readJugemu():
  with open('jugemu.txt', 'r') as f:
    for line in f:
      print('readJugemu')
      yield line

for l in readJugemu():
  print('main: ', end='')
  print(l.rstrip()[::-1])

図11 ハノイの塔の解を求めるPythonコード「hanoi.py」

#!/usr/bin/env python
  
def hanoi(n, src, via, dst):
  if n <= 1:
    yield src, dst
  else:
    yield from hanoi(n-1, src, dst, via)
    yield src, dst
    yield from hanoi(n-1, via, src, dst)

for src, dst in hanoi(3, 'A', 'B', 'C'):
  print(f'{src}->{dst}')

図12 yield from構文を使わない場合のコード

#!/usr/bin/env python
  
def hanoi(n, src, via, dst):
  if n <= 1:
    yield src, dst
  else:
    for s, d in hanoi(n-1, src, dst, via): yield s, d
    yield src, dst
    for s, d in hanoi(n-1, via, src, dst): yield s, d

for src, dst in hanoi(3, 'A', 'B', 'C'):
  print(f'{src}->{dst}')