ループ#

プログラムでは、同じ処理を繰り返し行いたい(ループさせたい)ことが多くあります。

基本的なループ構造#

forループ#

forループはリストやタプルといった集合的データ構造に対して、それぞれの要素に順番に処理するために用いられます。

t=['a','b','c','d','e']
for i in t:
    print (i)
a
b
c
d
e

range()#

range()という関数を使うと連続する数値からなるデータを得ることができますので、これを用いてfor文を書くことができます。主な目的は、ループの回数を指定したり、リストやタプルを作成したりする際に範囲を指定することです。

range(start, stop, step)

  • start: 範囲の開始値を指定します(デフォルトは\(0\)

  • stop: 範囲の終了値を指定します(指定した値より小さい値まで範囲が生成されます)

  • step: 範囲内の値の間隔を指定します(デフォルトは\(1\)

for i in range(1,6):
  print (i)
1
2
3
4
5
#startを省略した場合、デフォルトで0から開始されます。
for i in range(6):
  print (i)
0
1
2
3
4
5
for i in range(1,6,2):
  print (i)
1
3
5

while文によるループ#

while文には、与えられたループ条件とループ対象のコードブロックを記述します。

while文ではwhileの後の条件式がFalseとなるまで、もしくはループがbreakにより明示的に終了させられるまで、そのブロックが繰り返し実行されます。

x = 1
total = 0
while x <= 10:
    total += x
    x += 1
    print(x, total)
2 1
3 3
4 6
5 10
6 15
7 21
8 28
9 36
10 45
11 55
x=256 
total=0
while x>0:
    if total>500:
        break
    total+=x
    x=x//2
    print(x, total)
128 256
64 384
32 448
16 480
8 496
4 504

発展的なループの使い方#

ループ内の制御構造#

ある特定の条件が満たされた場合に、ループを途中で抜けたり、終わらせたくなるときがあります。これにより、柔軟にプログラムを取り組むことができます。

continue#

continueは以後の処理をとばして次の処理へいきます。以下の例では、item==3のとき、print(item)を飛ばして、item==4となるループに進みます。

for item in t:
    if item=='c':
        continue
    print (item)
a
b
d
e

break#

breakはループ自体を終了します。下の例では、item==cのときはbreakとなり、ループが終了します。

for item in t:
    if item=='c':
        break
    print (item)
a
b

pass#

passは「何もしない」ことを示す命令です。コードブロック内で必要なアクションがないことを示す時でよく用いられます。

for item in t:
    if item=='c':
        pass
    print (item)
a
b
c
d
e

ここで、ユークリッドの互除法というアルゴリズムの実装にトライしてみましょう。

ユークリッドの互除法とは、2つの整数、aとbの最大公約数を求めるアルゴリズムです。例えば、2485と1162の最大公約数を求めたい場合

\(2485 \div 1162 = 2 余り 161\)

\(1162 \div 161 = 7 余り 35\)

\(161 \div 35 = 4 余り 21\)

\(35 \div 21 = 1 余り 14\)

\(21 \div 14 = 1 余り 7\)

\(14 \div 7 = 2 余り 0\)

割る数と余りを次回の割られる数と割る数にして、次々と計算し、最後に割り切れたら終わりで、最後の割る数が最大公約数です。

#答え
a = 2485
b = 1162

例外処理#

プログラムが実行されると、実行中に予期しないエラーが発生することがあります。この場合、プログラムは停止してしまいます。

「エラーを無視してとにかくプログラムを最後まで実行させたい」「エラーが起こるときにエラーを回避するような仕組みをプログラム自体に実装したい」といった状況もあります。

try-except文を使用すると、エラーが発生した場合に特定の処理を実行し、プログラムの実行を継続することができます。

try-except文の基本的な構文は以下のとおりです。

  • tryブロック内には、エラーが発生する可能性があるコードが含まれます。

  • エラーが発生しない場合は、exceptブロックは実行されません。

  • エラーが発生した場合は、対応するexceptブロックが実行されます。

try:
    # ここにエラーが発生する可能性のあるコードを書く
except <エラーの種類>:
    # エラーが発生した場合に実行されるコードを書く

import math #sqrt(square root)関数を使うための1行
s = [1,4,16,-25,36,49,64,81,100,121,144]
#for i in range(20):
for i in s:
    print(math.sqrt(i)) 
1.0
2.0
4.0
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[11], line 5
      3 #for i in range(20):
      4 for i in s:
----> 5     print(math.sqrt(i)) 

ValueError: math domain error
import math
s = [1,4,16,-25,36,49,64,81,100,121,144]
for i in s:
    try:
        print(math.sqrt(i)) 
    except :    
        print("値が"+str(i)+"になったのでsqrtが計算できません")
1.0
2.0
4.0
値が-25になったのでsqrtが計算できません
6.0
7.0
8.0
9.0
10.0
11.0
12.0
s = [1,4,16,-25,36,49,64,81,100,121,144]
for i in s:
    try:
        print(math.sqrt(i)) 
    except :    
        continue
1.0
2.0
4.0
6.0
7.0
8.0
9.0
10.0
11.0
12.0

被除数が100である場合、リストの値を除数とする割り算の結果を順番に計算するプログラムを実装してください。

  • 計算結果をprintで表示してください

  • 計算不可能の場合、ラーメッセージだけを表示してエラーが起きた回数をカウントし、計算を続けてください

enumerate#

for文の繰り返し処理では、要素の順序を把握したいことがあります。

enumerate()関数を利用することで、for文内のループ処理にインデックス番号を付与できるのです。

例えば、2つの変数 i, d が指定されています。 i には \(0, 1, 2, …\) が順に代入されます。 val にはリストの要素が順に代入されます。

my_array = [ '1番目', '2番目', '3番目']
for i, d in enumerate(my_array):
    print('インデックス: ' + str(i) + ' 内容: ' + d )
インデックス: 0 内容: 1番目
インデックス: 1 内容: 2番目
インデックス: 2 内容: 3番目

以下にリストに基づいて、リストの要素を値、そのインデックスをキーとする辞書を作ってくだい。

#答え
l = ['Marx', 'Weber', 'Durkheim', 'Parsons', 'Merton']

zip#

zip()関数は、複数のイテラブル(リスト、タプル、セット、文字列など)から、要素をまとめて取り出すために使用される組み込み関数です。

具体的に言えば、対応する位置の要素をタプルにまとめ、新しいイテラブルなオブジェクトを作成します。

各タプルは、元のイテラブルの要素の数に基づいて作成されます。要素の数が一致しない場合は、最短のイテラブルに基づいてzipオブジェクトが作成されます。

numbers = [1, 2, 3]
letters = ['a', 'b', 'c']
zipped = zip(numbers, letters)
for pair in zipped:
    print(pair)
(1, 'a')
(2, 'b')
(3, 'c')

zip()関数は、新しいタプルを生成するために、各イテラブルの要素を1つずつ取り出し、ループをすることができます。

例えば、zip()関数を使用して、複数のリストでループを実行することができます。

numbers = [1, 2, 3]
letters = ['a', 'b', 'c']
for i, j in zip(numbers, letters):
    print(i, j)
1 a
2 b
3 c
for i, j in zip(numbers, letters):
    print(j, i)
a 1
b 2
c 3

2つのリストをzip関数を使ってループし、各リストの要素を合計し、その結果を新しいリストに格納するプログラムを作成してください。

#答え
list_a = [1, 2, 3, 4, 5]
list_b = [6, 7, 8, 9, 10]
sum_list = []

辞書のループ処理#

辞書の要素にわたって操作はよくあります。

  • 辞書 の全てのキーを変数keyに代入しながら、実行文を繰り返すには次のように書きます。

nation={'Marx': 'German',
 'Weber': 'German',
 'Durkheim': 'France',
 'Parsons': 'America',
 'Merton': 'America',
 'Goffman': 'America',
 'Habermas': 'Germany'}
for key in nation:
    print('Name:', key, ', Nationality:', nation[key])
Name: Marx , Nationality: German
Name: Weber , Nationality: German
Name: Durkheim , Nationality: France
Name: Parsons , Nationality: America
Name: Merton , Nationality: America
Name: Goffman , Nationality: America
Name: Habermas , Nationality: Germany
  • valuesメソッドを使えば(キーを使わずに)値を1つずつ取り出すこともできます。

for value in nation.values():
    print('Nationality:', value)
Nationality: German
Nationality: German
Nationality: France
Nationality: America
Nationality: America
Nationality: America
Nationality: Germany
  • itemsメソッドを使えばキーと値を一度に取り出すこともできます。

for key, value in nation.items():
    print('Name:', key, 'Nationality:', value)
Name: Marx Nationality: German
Name: Weber Nationality: German
Name: Durkheim Nationality: France
Name: Parsons Nationality: America
Name: Merton Nationality: America
Name: Goffman Nationality: America
Name: Habermas Nationality: Germany