【Python】for文で逆順にループする(逆暗号)
Pythonでfor文で逆順にループして表示する方法について解説します。
for文で逆順にループ
コード例
# for文で逆順に表示(文字列)
str1 = 'abcdef'
for s in reversed(str1):
print(s, end='')
実行結果
fedcba
reversed()関数によって変数str1に格納された文字列’abcdef’を逆順の’fedcba’にしています。
for文は並び式(このコードではreversed(str1))から1文字ずつ取り出して変数sに格納していきます。
このコードではend="によってそのまま連続して表示されていますが、削除してしまうと1文字ずつ改行されて出力されます。
このやり方はリストに対しても適応可能です。
コード例
# for文で逆順に表示(リスト)
list1 = [11, 22, 33, 44, 55]
for lst in reversed(list1):
print(lst, end=' ')
実行結果
55 44 33 22 11
わかりやすくするようにend=’ 'とスペース文字で区切って表示しています。
ただし表示されるのはリストではないイテラブルオブジェクトです。
リスト形式で表示させたいのならfor文では書きません。
コード例
# for文で逆順に表示(リストで表示)
list1 = [11, 22, 33, 44, 55]
print(list(reversed(list1)))
実行結果
[55, 44, 33, 22, 11]
リストで表示させるにはlist関数を使う必要があります。
次は数列を逆順にします。
コード例
# for文で逆順に表示(1までカウントダウン)
n = int(input('正の整数n : '))
for i in range(n, 0, -1):
print(i, end=' ')
実行結果
正の整数n : 3
3 2 1
このコードでは入力された正の整数値から1までのカウントダウンを表示しています。
このときrange()関数の第1引数はキーボードから入力されたnです。
第2引数は1までを表す0で第2引数は自身の数を含まないのでその直前の1が最後に表示されます。
第3引数は-1とすることで1ずつ減る逆順の数列を作ることができます。
第3引数を-1と指定することでこの逆順が実現できますがこの場合第2引数は省略できません。
ちなみに第3引数の部分を消去して実行すると何も表示されなくなります。
これはrange()関数は本来range(a, b)でa以上b未満の数列を生成することを期待しaがbより小さい値を想定しているためです。
逆暗号
メッセージを逆順にすることで暗号化することを逆暗号といいます。
この逆暗号のプログラムをfor文を使って実現します。
コード例
# 逆暗号(for文)
message = input('逆暗号したい文 : ')
print('逆暗号 : ', end='')
# 逆暗号を求める
for translated in reversed(message):
print(translated, end='')
実行結果
逆暗号したい文 : abcdef
逆暗号 : fedcba
キーボードに入力された文の逆暗号を求めています。
入力された文字列を変数messageに代入してfor文でreversed()関数によって逆順にして変数translatedに格納しています。
変数translatedには1文字ずつ格納されますがそのままだと1文字出力してはprint関数により改行してしまいます。
そのため第2引数をend="とし改行文字を空文字列に変えています。
こうすることで文字列が逆順につながって表示されます。
for文はwhile文にも書き換えられます。
コード例
# 逆暗号(while文)
message = input('逆暗号したい文 : ')
# 逆暗号を求める
translated = ''
i = len(message) - 1
while i >= 0:
translated += message[i]
i -= 1
print('逆暗号 : ', translated)
実行結果
逆暗号したい文 : abcdef
逆暗号 : fedcba
同じ逆暗号をwhile文によって書き換えています。
まず変数translatedを空文字列で生成します。
次に変数iにlen(message)すなわち変数messageに格納された文字数から1引いた数を格納します。
while文では変数translatedにmessage[i]を加えていきます。
どう加えられていくのかの過程を確認するために文を追加します。
コード例
# 逆暗号(while文・過程を表示)
message = input('逆暗号したい文 : ')
# 逆暗号を求める
translated = ''
i = len(message) - 1
while i >= 0:
translated += message[i]
print(f'i = {i}, message[i] = {message[i]}, translated = {translated}')
i -= 1
print('逆暗号 : ', translated)
実行結果
逆暗号したい文 : abcdef
i = 5, message[i] = f, translated = f
i = 4, message[i] = e, translated = fe
i = 3, message[i] = d, translated = fed
i = 2, message[i] = c, translated = fedc
i = 1, message[i] = b, translated = fedcb
i = 0, message[i] = a, translated = fedcba
逆暗号 : fedcba
while文の中にiの値、message[i]の値、translatedの値が表示されるように文を追加しました。
iの値は5から1ずつ減少し最後は0になっています。
message[i]の値から逆順に1文字ずつ取り出されているのがわかります。
それがtranslatedに1文字ずつ代入されているのがわかります。
その後iの値を1だけデクリメントして条件式を評価します。
iが0より小さくなると条件式がFalseになるのでwhile文から抜けるためループが終了します。
追加した文ではそれぞれの値をf文字列で表示させています。式が直接埋め込めるので見やすくなります。
どちらでも実現できますが見てわかるようにwhile文よりもfor文が短く記述できるので基本はfor文で書くのが望ましいです。