【Python】コピペいらず!?同じ処理を繰りかえそう
たとえば、
「同じ処理を繰り返したい」とき
ってありませんでしょうか?
それはfor文、while文を使えば解決してくれるかもしれません。
このNoteを読めば
「コピペを繰り返す」必要
がなくなります。
それではいろいろと見ていきましょう。
for文で繰りかえそう
順番に番号を指定すると
「倍に時間」
がかかってしまいますよね?
for文を使えば、少なくてすみます。
書き方は
for [一つ一つの中身の名前] in [リストの変数]:
<処理>
でOKです。
たとえば、
fruits=['grape','banana']
for fruit in fruits:
print('fruits:{0}'.format(fruit))
と書くことができます。
enumerateメソッドで、要素の番号、インデックスを取り返そう
また、要素の番号も取り出したいときもありますよね?
そのときは、inのあとに
「enumerateのメソッド」
を使います。なので
for [インデックスの変数],[一つ一つの中身の名前] in enumerate([リスト型の変数]
というふうに書きます。コードの例をあげてみます。
fruits=['grape','banana']
for i,fruit in enumerate(fruits):
print('{0}番目:{1}'.format(i,fruit))
とすることで、
0番目:grape
1番目:banana
となり、「変数の要素番号(インデックス)と変数の中身」を同時にとれていることがわかります。
○回ループ、特定の数字から始めたいときはrange関数を
また、変数のループに限らず、
「ある特定の回数」でループをしたい
もしくは、
「ある特定の数字」からはじめたい
というときもありますよね?
そのときは、
for [変数] in range([開始番号],最終番号):※開始番号は省いてもOK!(その時は0から始まります。)
の
「rangeメソッドを使ってfor文を作る」
と良いです。
たとえば、
for i in range(5):
print(i)
と書くことで、
0
1
2
3
4
となり、
「rangeで作られた数字の配列をもとにループが回っている」
ことがわかります。
zip関数は1回ずつ「異なる変数」の配列たちをそれぞれの変数に割り当てる関数
Python繰り返し構文のfor文の組み合わせにzip関数が使われるときがあります。zip関数は簡単に言いますと、
「異なる変数」の配列たち
を
それぞれ1回のループで1つずつ取り出し、for文のあとに指定した変数たちに割り当てる関数
となります。言葉で説明するとややこしいので、まずは、書き方から見てみましょう。
for [変数,変数2,...] in zip(配列,配列2,...):
...#コードを書いていきます。
となります。
えっ、別々の異なる配列を1つずつ順番に取り出し、対応した順番ごとにそれぞれの変数に割り当てるのってなんかメリットがあるの?
と思われるかもしれません。
なので、いまいちピンときませんね🤔では、仮にこう考えてみましょう。たとえば、以下の表のように、まず、3つの変数がそれぞれすべての番号において、
1、2、3
で対応するものとします。
たとえば、上の図をご覧ください。3つの変数の中に、
subscName→ある定額音楽配信サービス、あるプログラミング講座・・・ degree →1カ月、1年・・・ cost→980円、4980円・・・
cost →980円、4980円
のように、変数と変数との順番が、
それぞれに何か関連づいている変数
とします。この場合、
subscName = ['ある定額音楽配信サービス', 'あるプログラミング講座']
degrees = ["1カ月", "1年"]
costs=["980円","4980円"]
for subscName, degrees, costs in zip(subscName, degrees,costs):
print(subscName, degrees, costs)
実行結果はこちらです↓
ある定額音楽配信サービス 1カ月 980円
あるプログラミング講座 1年 4980円
とすれば、一気に取り出せて便利ではないでしょうか?ちゃんと無事に移りましたね。仮に、zip関数を使わない場合、
subscName = ['ある定額音楽配信サービス', 'あるプログラミング講座']
degrees = ["1カ月", "1年"]
costs=["980円","4980円"]
for i,subscName in enumerate(subscName):
print(subscName, degrees[i], costs[i])
というふうにenumerateでもできないことはないと思いますが、変数subscNameのほかの変数は、配列にアクセスするのに、
要素番号の指定がいるので、タイプの数が増えてしまう
いささか不便なのではないのかと感じてもらえたのではないかと思います。そんなときにzip関数は便利です。タイプミスを減らすために少しでもコードの量を少なくしておきたいものです。
【応用編】さらに深掘り!!zip関数の戻り値の中身とは?
zip関数に対するさらなる理解を深めるために、zip関数の戻り値についてみていきましょう。では、実際に以下のコードを打ち込み、zip関数の戻り値を見てみましょう。
subscName = ['ある定額音楽配信サービス', 'あるプログラミング講座']
degrees = ["1カ月", "1年"]
costs=["980円","4980円"]
print(zip(subscName, degrees,costs))
<zip object at 0x106cac880>
このように、zipオブジェクトで返されます。これだけでは、活用しずらいですし、ちょっと深掘りとは言えません…🤔そこで、list関数でlist型に変換してみます!!
subscName = ['ある定額音楽配信サービス', 'あるプログラミング講座']
degrees = ["1カ月", "1年"]
costs=["980円","4980円"]
print(list(zip(subscName, degrees,costs)))
もちろん上のコードのようにlist関数でlist型にも変えることができますが、
[('ある定額音楽配信サービス', '1カ月', '980円'), ('あるプログラミング講座', '1年', '4980円')]
となります。
あれ!?[](リスト型)ではなく、()(タプル型)で書かれているぞ!!?
思ったかもしれません。ですので、zip関数で返される変数の中身はtuple関数を通してみると、
タプル型の配列
となります。なので、
「tuple変数で変換」
したほうがいいのかもしれません🤔
なので、
「zip関数の順番とfor文の変数の順番が対応」
しているかどうかきちんと確認しましょう。
for in …の「…」に入るのはイテラブルな変数
実は、for in …の「…」に入るのはイテラブルなら何でも入れることができます。ではイテラブルとは何でしょうか?
イテラブルは英語のiterableであり、一つずつ分解をすると、
iterate(繰り返す)+-able(可能を示す)
となります。つまり、 「繰り返せる」 という意味になります。言い換えれば、
リスト型のように「一つずつ前にすすめる」型
を指します。
なんのこっちゃ!!!?
意味がわからないと思うので、まずは、イテラブルに当たる型を、解説していきます。
①リスト型
リスト型はプログラミングでいう配列です。
「1つの変数にそれぞれ連番が振られた変数のまとまり」
だと思ってください。図に示すと、以下の感じになります。
上の図の通り、連続して変数を一つずつ取り出すことができますから、リスト型は、イテラブルであると言えます。
②文字列型
これは意外なのかもですが、文字列もイテラブルの型に入ります。文字列型は文字通り、
「文字+列=文字の連続」
なので、繰り返せます。図に表すとこんな感じになります。なので、以下のコードを実行すると、1文字ずつ出ていることがわかります🤔
for letter in '345あ':
print(letter)
なので、文字列型は「イテラブル」ですね。
③辞書型
辞書型は一見、連続したり、するようには見えず、辞書におけるキーを連続に取れないと、思いがちです。ですが、順番は保証されていなくても(Python3.7以降は順番が保障されるようになった☺️)
「キーを連続」
して取り出すことはできます。実際に、辞書型を作り、for in 文に入れてみましょう。
dict={'in':'Inのキーの中身です。','out':'outのキーの中身です。'}
for key in dict:
print(key)
そうすると、キーだけが実行結果に表示されることがわかります🤔
<実行結果>
in
out
これを知っておくだけで、特定のキーの動作の場合分けできますね😊
では、逆にイテラブルに当たらない型とは何でしょうか?それは、
数値型
です。数値型には、
int型
float型
︙
などいろんな型がありますが、イテラブルじゃないとなると、ピンとこないかもしれません。
よくよく考えてみれば、イテラブルでない型は、変数の集まりを持たない型ですから、連続してすすめることができないと覚えれば、for in 文に入れてはいけないと感じることができるかもしれません🤔
#実際に入れると、TypeErrorとなり、実行できません。
for i in 3:#int型
print(i)
for i in 3.5:#float型。小数点が入っていると、そもそも、数えられません🥺そう考えると、小数点の数字はfor文に入れられないことがわかりますよね🤔
print(i)
このようにイテラブルな型とは、要素ごとに一つずつ前に進められる型を指します。
while文でも繰りかえしてみよう。
while [条件式]:
<処理>
︙
と書くのですが、
ただしこのままでは
無限ループ=永久にループ♻
に陥ってしまうので
「ループが終わるように処理をする」
のがポイントです。
たとえば、10から1を表示したいとき、
x=10
while x>0:
print(x)
x-=1
というふうに書くと良いです。こうすることで、
無限ループの危険性を回避したまま、
「whileでループを回す」
ことができます。
ループ途中でのスキップはcontinueで。抜け出したいときはbreakで。
ループを組んだけど、
①途中で抜け出したい
②ある処理では、ループを途中で終わらせたいけど、ループを止めたくない
・・・ってことありませんか?そのときには、
「breakとcontinue」
がその夢を叶えてくれます。
break文とcontinue文はそれぞれ、
break文・・・実行されるとすぐに、ループを抜ける。
continue文・・・実行されると、以降の文は実行されないが、ループを回し続ける。
の意味になります。ざっと説明したところで
「ピンと来ない」
と思うので、例をつかって、説明してみます。
break文を使った例:
for i in range(5):
if i==2:
break
print(i)
出力結果:👇
0
1
で途中でループが抜けていることがわかります。
continue文を使った例:
for i in range(5):
if(i==2):
continue
print(i)
出力結果:👇
0
1
3
4
のように
iが2のときだけ「continue文以降の処理がスキップ」された上
で、
「ループされている」
ことがわかります。
このように、
「BreakとContinue」
は、for文、while文に限らず
「ループ処理」
ならば使える重要な文なので、ぜひ覚えておきましょう。
まとめ
今回は、主に繰り返しの文に使われる
・for〜in文(+関数)
・while文
・continueとbreak
を紹介しました。
👆以上のものを使いこなすことで、
「同じコピペの作業をせず」に
作ることができるので、試してみてください。