python勉強6日目 0 から 9 までの数について、円周率の小数部分 (第千位まで) に表れる回数をそれぞれ求め出力するプログラム
これは、僕が最高のエンジニアになるまでの物語だ。
今日はこちらの問題を僕なりに解釈する。
問題
円数率の小数点以下1000位までにおいて、「0〜9」の各数字が何回出現したかカウントして、順番に出力するプログラムを書け。
解き方
# ここにコードを書いてください
en = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989"
zero = 0
one = 0
two = 0
three = 0
four = 0
five = 0
six = 0
seven = 0
eight = 0
nine = 0
for number in en[2:]:
if(number == "0"):
zero += 1
elif (number == "1"):
one += 1
elif(number == "2"):
two += 1
elif(number == "3"):
three += 1
elif(number == "4"):
four += 1
elif(number == "5"):
five += 1
elif(number == "6"):
six += 1
elif(number == "7"):
seven += 1
elif(number == "8"):
eight += 1
else:
nine += 1
print(zero)
print(one)
print(two)
print(three)
print(four)
print(five)
print(six)
print(seven)
print(eight)
print(nine)
僕が頑張って捻り出した答え。かなり長い。
仕組みとしては
まず、各数字が出現したときにカウントする変数を定義する。
次に変数enに円周率(小数点以下第1000位まで)をstr型(文字列)として代入する。
次に変数numに円周率の小数点以下第1000位までをstr型として代入する。
次に文字列を1つ1つ調べて、各数字をカウントする変数の値を+1ずつ変化させる(※)
最後に、各数字の出現回数を変数を介して出力する。
※文字列に対してfor文を用いると、1文字単位でスライスできる
for i in "Hello":
print(i)
#
H
e
l
l
o
模範解答
PI = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989"
num_dict = dict()
for number in PI[2:]: # 小数部分 (第千位まで) をカウントする
num_dict[number] = num_dict.get(number, 0) + 1
# 0 から 9 までの数字について答えを順に出力する
# number_dict は数字を文字として扱っていることに注意!
for number in range(10):
print(num_dict.get(str(number), 0))
なるほど、分からん。
コードを一行ずつ見ていこう。
一行目。
PI = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989"
これは変数PIに円周率をstr型として代入しているということ。
二行目
num_dict = dict()
これは変数num_dictに空の辞書を代入しているということ。
dict()関数は、中身が空っぽの辞書を作る関数だ。
実際、print(num_dict)を実行するとこうなる。
num_dict = dict()
print(num_dict)
# {}
三行目
for number in PI[2:]:
変数numberに小数点以下を1文字ずつ代入する。
四行目
num_dict[number] = num_dict.get(number, 0) + 1
空の辞書に名前(key)と値(value)を入れたりしている。
ここで、辞書に新しくkey:valueを入れる方法をおさらいする。
例えば以下のような辞書があったとする
yatai = {"焼きそば":300,"かき氷":100}
この辞書に新しく、要素(「"フランクフルト":200」)を追加したい場合
辞書名["key"]= バリュー
といった形でコードを書く。
具体的には以下のような感じだ。
yatai["フランクフルト"] = 300
# {'焼きそば': 300, 'かき氷': 100, 'フランクフルト': 200}
つまり四行目の前半
num_dict[number] =
この部分の「num_dict」は辞書名で、[number]は変数number(の値)をkeyとして辞書に登録(追加する)という意味だ。
=があるので変数の定義だと勘違いしないように注意。
そして四行目の後半
num_dict.get(number, 0) + 1
変数num_dict(の値)+1をvalueとして辞書に登録する(追加する)という意味になるが、「get()メソッドに関する知識」と「辞書の上書きの知識」が必要だ。
まず、get()メソッドについて。
辞書で特定の要素にアクセスしたい時は[key名]でアクセスするが
yatai = {"焼きそば":300, "かき氷":100 , "フランクフルト":200}
print(yatai["フランクフルト"])
#200
この際、要素にないキーを指定するとエラーとなる。
yatai = {"焼きそば":300, "かき氷":100 , "フランクフルト":200}
print(yatai["焼き鳥"])
# File "./main.py", line 2, in <module>
print(yatai["焼き鳥"])
KeyError: '焼き鳥'
そこで活躍するのがget()メソッド。
これを使えば要素にないキーを指定した時に何を表示表示するか(値)を設定することが出来る。
get()メソッドを使う場合は
「[key名]」
ではなく
「辞書名.get(key名,keyがない場合に表示する値)」
とコーディングする。
yatai = {"焼きそば":300, "かき氷":100 , "フランクフルト":200}
print(yatai.get("焼き鳥","売ってません"))
#売ってません
といった感じだ。
次に辞書の上書きについて。
「辞書名[ key名] = 値」
とコーディングすることで、valueを変更できる
yatai = {"焼きそば":300, "かき氷":100 , "フランクフルト":200}
yatai["焼きそば"] = 250
print(yatai)
#{'焼きそば': 250, 'かき氷': 100, 'フランクフルト': 200}
つまり四行目
num_dict[number] = num_dict.get(number, 0) + 1
は、keyとして変数numberの値を、valueとして変数num_dict + 1の値を追加する(変数num_dictの値がない場合は0をvalueに追加する)という意味となる。
つまり、この時点で辞書は完成している。
実際辞書を出力「print(num_dict)」するとこうなる。
PI = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989"
num_dict = dict()
for number in PI[2:]:
num_dict[number] = num_dict.get(number, 0) + 1
print(num_dict)
#{'1': 116, '4': 93, '5': 97, '9': 106, '2': 103, '6': 94, '3': 102, '8': 101, '7': 95, '0': 93}
あとは、これをどう整えて出力するかだ。
考え方としては
「print(num_dict["0"])」「print(num_dict["1"])」
…とkeyの値を0から順番に指定して出力すればいい。
ということは、そうだ。「for 変数名 in range(10):」だ。
実際、模範解答も
for number in range(10):
このようになっている。
そしてこの下(最後のコード)がまた複雑だ。
print(num_dict.get(str(number), 0))
まず、注目すべきはstr(number)の部分。
ここで、数字をint型からstr型に変換している。(「0」という数字から「"0"」という文字列に変換している)これはもちろん、辞書のkeyが文字列(str型)だからだ。
次に、get()メソッドでエラー回避をしているが…正直意味不明だ。
print(num_dict[str(number)])
で問題なく出力できる。(アルゴ式でも正解判定となる)
range()の範囲を間違えた時対策だろうか?
なぜget()メソッドが使われているか、分かる方いたらコメントで教えてほしい。
この記事が気に入ったらサポートをしてみませんか?