gotutiyan’s blog

プログラミング関連の話題を中心に

【python3.x】 練習問題55本ノック【問題と解答】

はじめに

ここではpythonの練習問題を掲載しています.

データを処理する際には,必ず「データの格納」と「データの取り出し」を行うことになるので,その方法を知ることを目的としています.問題は暗算で解けるものや,頭の中で答えが分かるものが多数ありますが,あくまでも,「行いたい処理をpython3という言語ではどのように表現するのか」を確認するものです.

このページは,問題とその解答が掲載されているページです.問題だけのページは以下のリンクからどうぞ.

gotutiyan.hatenablog.com

全ての問題には,必ず出力が存在します.出力はprint()を用いて,画面に表示させることを想定しています.

問題と解答

1. 変数

xという変数に2を代入し,それを3倍した数を出力してください.

期待する出力:6

解答

x = 2
print(3 * x)
2. swap

変数a100を代入し,変数b200を代入します.その後,両者の値を入れ替えて,a200b100が代入されているようにしてください.出力としてはabを出力してください.出力形式は問いませんが,print(a,b)とすると,空白区切で出力できます.

期待する出力の一例:200 100

解答

a = 100
b = 200
a, b = b, a
print(a, b)
  • 1つの代入式で複数の変数を扱えます.
3. 四則演算+\alpha

変数a10を代入,変数b2を代入し,abの和,差,積,商を出力してください.出力形式は問いません.また,商の値が小数か整数かは問いません.

期待する出力の一例:12 8 20 5.0

解答

a = 10
b = 2
print(a+b, a-b, a*b, a/b)
  • 割り算は,/だと結果が小数で,//だと結果が整数で得られます.
4. 余り

変数a5を代入,変数b3を代入し,abで割った時の余りを求めてください.

期待する出力:2

解答

a = 5
b = 3
print(a%b)
5. べき乗

変数a5を代入,変数b10を代入し,ab乗,つまりa^bを出力してください.

期待する出力:9765625

解答

a = 5
b = 10
print(a**b)
6. if,比較演算子<, >

変数a5を代入,変数b10を代入し,abのうち大きい方を出力してください.

期待する出力:10

解答

a = 5
b = 10
if a < b:
    print(b)
else:
    print(a)
  • ifやforを書く際には,どこまでがその対象かを表すブロックを作る必要がありますが,pythonではインデントによってこれを示します.
7. 比較演算子==, bool

変数a5を代入し,aが偶数ならTrue,そうでなければFalseを出力してください.(条件式をそのままprintすれば良いです.)

期待する出力:False

解答

a = 5
if a % 2 == 0:
    print(True)
else:
    print(False)
# もしくは
print(a%2 == 0)
  • 比較演算子==, !=, <, >, >=, <=)はbool型と呼ばれるTrueFalseのいずれかを返します.
8. 文字列(ランダムアクセス)

変数に,'python'という文字列を代入し,先頭の文字を0番目として2番目の文字を出力してください.

期待する出力:t

解答

s = 'python'
print(s[2])
  • 文字列は,[ ]を使うことで,文字を抽出できます.
  • [2]のように,[ ]の中に指定する数値を添え字(index)と呼びます.
9. 文字列(結合)

'py''thon'という2つの文字列をそれぞれ変数に代入し,結合したものを出力してください.

期待する出力:python

解答

s1 = 'py'
s2 = 'thon'
print(s1 + s2)
  • 文字列は,+を用いることで結合できます.
10. 文字列(format)

変数a5を,変数b3を代入し,これらの変数を用いて'5%3=2'という文字列を出力してください.

期待する出力:5%3=2

解答

a = 5
b = 3
ans = "{}%{}={}".format(a, b, a%b)
print(ans)
  • {}の記号を含んだ文字列に対して,.format()で数値や文字列を入れられます.
11. 文字列(replace)

変数に文字列'some1'を代入し,この文字列中の1oneに変換してください.

期待する出力:someone

解答

s = 'some1'
s = s.replace('1', 'one')
print(s)
12. 文字列(lower)

変数に文字列'This Is A Sentence .'を代入し,この文字列を全て小文字に変換してください.

期待する出力:this is a sentence .

解答

s = 'This Is A Sentence .'
s = s.lower()
print(s)
  • .lower()を用いることで,全ての文字が小文字になります.
13. 文字列(upper)

変数に文字列'This Is A Sentence .'を代入し,この文字列を全て大文字に変換してください.

期待する出力:THIS IS A SENTENCE .

解答

s = 'This Is A Sentence .'
s = s.upper()
print(s)
  • upper()を用いることで,全ての文字が大文字になります.
14. 文字列(文字数)

変数に文字列'How many characters?'を代入し,この文字列の文字数を出力してください.空白も含めるものとします.

期待する出力:20

解答

s = 'How many characters?'
print(len(s))
  • 文字列の長さはlen()で見ることができます.
  • len()は,頻繁に使用する汎用的なメソッドで,後述するリストの長さを得るときにも使います.
15. 文字列 → 数値

変数aに文字列'34'を代入し,変数bに文字列'43'を代入し,これらを数字と見なした時の和を出力してください.

期待する出力:77

解答

s1 = '34'
s2 = '43'
print(int(s1) + int(s2))
  • 文字列をint()で囲むことにより,数値に変換できます.これにより,四則演算などができます.
16. リスト

変数にリスト[1,2,3,4,5]を代入し,(先頭を0番目として)3番目の要素を出力してください.

期待する出力:4

解答

li = [1,2,3,4,5]
print(li[3])
  • 文字列と同じように,前から3番目の要素を見るときには[ ]を使用します.
  • 文字列は,リストの各要素が文字になっているものだと思うと良いかもしれません.
17. リスト(結合)

変数li1[1,2,3]のリストを代入,変数li2[4,5]のリストを代入し,2つのリストを結合して出力してください.

期待する出力:[1,2,3,4,5]

解答

li1 = [1,2,3]
li2 = [4,5]
print(li1 + li2)
18. リスト(append)

変数にリスト[1,2,3,4,5]を代入し,このリストの末尾6,7を1つずつ順番に追加してください.その後,最終的なリストを出力してください.

期待する出力:[1,2,3,4,5,6,7]

解答

li = [1,2,3,4,5]
li.append(6)
li.append(7)
print(li)
19. リスト(insert)

変数にリスト[1,2,3,4,5]を作成し,先頭を0番目としたときに,0番目と1番目の間に100を挿入してください.

期待する出力:[1,100,2,3,4,5]

解答

li = [1,2,3,4,5]
li.insert(1, 100)
print(li)
20. リスト(forによる捜査)

変数に[1,2,3,4,5]の5つの要素を持つリストを格納して,偶数の要素だけ出力してください.出力形式は問いません.

期待する出力:2 4

解答

li = [1,2,3,4,5]
for elem in li:
    if elem % 2 == 0:
        print(elem)
  • for 変数 in リストとすることで,[ ]を用いることなく,要素を先頭から順番に見ることができます.
21. リスト(forによる捜査, enumerate)

変数に[1,2,3,4,5]の5つの要素を持つリストを格納して,添え字が偶数番目の要素だけ出力してください.出力形式は問いません.ただし,先頭の添え字を0番目とします.

期待する出力:1 3 5

解答

li = [1,2,3,4,5]
for idx, elem in enumerate(li):
    if idx % 2 == 0:
        print(elem)
  • enumerate(リスト)を用いることで,リストの要素と共にその添え字も得られます.
  • 添え字と要素の組みが得られるので,それを受け取る変数も2つ書きます.ここではidxに添え字,elemに要素が順次代入されます.
22. リスト(len)

変数にリスト[11,22,33,44,55,66]を代入し,リストの要素数を出力してください.

期待する出力:6

解答

li = [11,22,33,44,55,66]
print(len(li))
23. リスト,if(存在確認)

リスト[11,22,33,44,55]に,値44が存在するかどうかをifを用いて判定してください.存在すればTrue,そうでなければFalseを出力します.

期待する出力:True

解答

li = [11,22,33,44,55,66]
if 44 in li:
    print(True)
else:
    print(False)
  • if 要素 in リストとすることで,値がリストに存在した時のみ発動する処理が書けます.
  • for 要素 in リストと形が似ていますが,forとifで意味が全然異なるので注意してください.
24. タプル,リストの負の添え字

変数に[1,2,3,4,5]の5つの要素を持つリストを格納して,リストの先頭の要素と末尾の要素をタプルとして格納し,出力してください.

期待する出力:(1, 5)

解答

li = [1,2,3,4,5]
tup = (li[0], li[-1])
print(tup)
  • タプルはリストと似ていますが,一度値を代入すると,2度と変更できない点が特徴です.
  • リストは[ ]で囲みますが,タプルは( )で囲みます.
  • 添え字に負の値を用いると,「末尾から何番目」を指定できます.末尾から-1, -2...です.
25. 辞書

変数に,値の組みとして{'A':1, 'B':2, 'C':3, 'D':4, 'E':5}を持つ辞書を格納して,出力してください.

期待する出力:{'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5}

解答

d = {'A':1, 'B':2, 'C':3, 'D':4, 'E':5}
print(d)
  • 辞書はキーと値(バリュー)を持つデータ構造です.
  • キーと値の型はなんでも良く,ここではキーに文字列,値に数としています.
26. 辞書(keys)

変数に,値の組みとして{'A':1, 'B':2, 'C':3, 'D':4, 'E':5}を持つ辞書を格納して,キーを要素としたリストを作成し,出力してください.

期待する出力:['A', 'B', 'C', 'D', 'E']

解答

d = {'A':1, 'B':2, 'C':3, 'D':4, 'E':5}
print(list(d.keys()))
  • .keys()とすることで,登録されている全てのキーが得られます.
  • .keys()の時点では特殊な型をしているので,リストにするには明示的にlist()で囲みます.
27. 辞書(values)

変数に,値の組みとして{'A':1, 'B':2, 'C':3, 'D':4, 'E':5}を持つ辞書を格納して,値(バリュー)を要素としたリストを作成し,出力してください.

期待する出力:[1,2,3,4,5]

解答

d = {'A':1, 'B':2, 'C':3, 'D':4, 'E':5}
print(list(d.values()))
  • .values()とすることで,登録されている全ての値が得られます.
  • .values()の時点では特殊な型をしているので,リストにするには明示的にlist()で囲みます.
28. 辞書(items)

変数に,値の組みとして{'A':1, 'B':2, 'C':3, 'D':4, 'E':5}を持つ辞書を格納して,キーと値(バリュー)の組みのタプルを要素としたリストを作成し,出力してください.

期待する出力:[('A', 1), ('B', 2), ('C', 3), ('D', 4), ('E', 5)]

解答

d = {'A':1, 'B':2, 'C':3, 'D':4, 'E':5}
print(list(d.items()))
  • .items()とすることで,登録されている全てのキーと値の組が得られます.
  • .items()の時点では特殊な型をしているので,リストにするには明示的にlist()で囲みます.この時,キーと値の組はタプルで表されます.
29. 辞書(キーの存在確認)

今,以下のように辞書が作成済みです.

d = {'apple':10, 'grape':20, 'orange':30}

この辞書に対して,'apple'というキーが存在するかを確認し,存在しなければ,'apple'というキーに対して-1という値を追加してください.また,同様のことを'pineapple'でも行なってください.その後,最終的な辞書を出力してください.

期待する出力:{'apple': 10, 'grape': 20, 'orange': 30, 'pineapple': -1}

解答

d = {'apple': 10, 'grape': 20, 'orange': 30, 'pineapple': -1}
d['apple'] = d.get('apple', -1)
d['pineapple'] = d.get('pineapple', -1)
print(d)
  • .get(キー)は,辞書にキーが既に登録されているかどうかを調べます.もし登録されていればキーに対応する値を,そうでなければNoneを返します.
  • .get(キー, 初期値)のように第二引数を与えると,キーが登録されていなかった場合に自動でそのキーを登録します.この時,対応する値は第二引数になります.
30. スライス1

変数に文字列'training'を代入し,先頭を0番目として,1番目から4番目までを取り出して出力してください.

期待する出力:rain

解答

s = 'training'
print(s[1:5])
  • 添え字を[a:b]とすると,[a, b)の範囲で切り取られます.ここでbは開区間なので,実際には含まれません.このような表記をスライスと呼びます.
31. スライス2

変数に文字列'understand'を代入し,先頭を0番目として,奇数番目の文字列だけを取り出した文字列を出力してください.

期待する出力:nesad

解答

s = 'understand'
print(s[1::2])
  • [a:]のように書いた場合,開始の添え字はaで,終了の添え字は末尾になります.(正確には末尾+1です.とにかく最後までの範囲を取ってくれます.)
  • [a:b:c]のように書いた場合,cは間隔を表します.具体的には,c-1飛ばしになります.上記の例だと,添え字2から1つ飛ばしで末尾まで,という指示になります.
32. スライス3

変数にリスト[1,2,3,4,5]を格納して,これを逆順に出力してください.

期待する出力:[5,4,3,2,1]

解答

li = [1,2,3,4,5]
li = li[::-1]
print(li)
  • 間隔として-1を設定すると,先頭に向かって1つずつ戻ることになります.上記のように全範囲を指定した時,最初末尾に飛んで,そこから先頭に戻るような挙動をするので,結果として逆順に見ることと等しくなります.
33. 集合

変数にリスト[1,1,2,3,3,4,5]を代入し,このリストを集合に変換して出力してください.

期待する出力:{1,2,3,4,5}

解答

li = [1,1,2,3,3,4,5]
se = set(li)
print(se)
  • リストをset()で囲むと集合になります.
  • 集合は,要素の重複を許しません.元のリストに同じ要素が複数存在しても,1つしか残りません.
34. 積集合

変数set1に集合{1,2,3,4,5},変数set2に集合{3,4,5,6,7}を代入し,積集合を出力してください.

期待する出力:{3,4,5}

解答

set1 = {1,2,3,4,5}
set2 = {3,4,5,6,7}
print(set1 & set2)
35. 和集合

変数set1に集合{1,2,3,4,5},変数set2に集合{3,4,5,6,7}を代入し,和集合を出力してください.

期待する出力:{1,2,3,4,5,6,7}

解答

set1 = {1,2,3,4,5}
set2 = {3,4,5,6,7}
print(set1 | set2)
36. 差集合

変数set1に集合{1,2,3,4,5},変数set2に集合{3,4,5,6,7}を代入し,差集合を出力してください.

期待する出力:{1,2}

解答

set1 = {1,2,3,4,5}
set2 = {3,4,5,6,7}
print(set1 - set2)
37. 型の確認

3つの変数に以下のように代入したコードがあります.各変数の型を出力してください.出力形式は問いません.

data1 = {'A':1, 'B':2}
data2 = "hoge"
data3 = {1,2,3,4,5}

期待する出力:<class 'dict'> <class 'str'> <class 'set'>

解答

data1 = {'A':1, 'B':2}
data2 = "hoge"
data3 = {1,2,3,4,5}
print(type(data1), type(data2), type(data3))
  • type()を用いることで,データの型を確認できます.
38. strip

文字列'This is sentence .\n'の改行記号を消したものを出力してください.

期待する出力:This is sentence .

解答

s = 'This is sentence .\n'
print(s.rstrip())
  • rstrip()は,文字列の末尾にある空白や改行記号を削除します.rはrightのrです.
  • 他にも,両端を処理するstrip()や,先頭だけを処理するlsrtip()もあります.
39. split

変数に文字列'C C++ // python java'を代入し,この文字列を空白で区切った後のリストを出力してください,また,同じことを'/'でも行い,出力してください.

期待する出力:['C', 'C++', '//', 'python', 'java'],['C C++ ', '', ' python java']

解答

s = 'C C++ // python java'
print(s.split())
print(s.split('/'))
  • splitは,文字を指定して文字列を分割するものです.何も指定しなければ,空白で分割されます.
  • 分割の結果はリストで得られます.
40. join

変数にリスト['This', 'is', 'a', 'sentence']を代入し,これらを空白区切で結合した文字列を出力してください.

期待する出力:This is a sentence

解答

words = ['This', 'is', 'a', 'sentence']
sent = ' '.join(words)
print(sent)
  • joinは,リストの要素を結合するものです.'結合文字'.join(リスト)という形で使います.
  • 今回は結合文字として空白を用いていますが,例えば'---'.join(words)とすればThis---is---a---sentenceが得られます.
41. max

変数にリスト[11,2,7,13,5]を代入し,最大値を出力してください.

期待する出力:13

解答

li = [11,2,7,13,5]
print(max(li))
42. min

変数にリスト[11,2,7,13,5]を代入し,最小値を出力してください.

期待する出力:2

解答

li = [11,2,7,13,5]
print(min(li))
43. sum

変数にリスト[11,2,7,13,5]を代入し,総和を出力してください.

期待する出力:38

解答

li = [11,2,7,13,5]
print(sum(li))
44. 昇順ソート

変数にリスト[5,3,1,4,2]を格納し,昇順に並び替えたリストを出力してください.

期待する出力:[1,2,3,4,5]

解答

li = [5,3,1,4,2]
sorted_li = sorted(li)
print(sorted_li)
  • sorted()を用いれば,リストをソートできます.デフォルトでは昇順ソートです.
45. 降順ソート

変数にリスト[5,3,1,4,2]を格納し,降順に並び替えたリストを出力してください.

期待する出力:[5,4,3,2,1]

解答

li = [5,3,1,4,2]
sorted_li = sorted(li, reverse=True)
print(sorted_li)
  • パラメータとしてreverse=Trueを指定すれば降順ソートになります.
  • 他にも,パラメータkeyを指定すれば,柔軟なソートが可能になります.(これは演習2で詳しく)
46. range()

0から99の100の要素からなるリストを出力してください.

期待する出力:[0,1,2....,99](一部省略)

解答

li = list(range(0,100))
print(li)
  • range()は指定の範囲で整数列を生成しますが,そのままでは特殊な型なので,リストにするには明示的にlist()で囲みます.
47. 内包表記

変数にリスト[5,4,3,2,1]を代入し,要素と添字の値(先頭を0とする)を足し合わせた数値を要素に持つリストを新たに作成してください.
内包表記を使うと便利です.

期待する出力:[5,5,5,5,5]

解答

li = [5,4,3,2,1]
ans_li = [idx + elem for idx, elem in enumerate(li)]
print(ans_li)
  • 内包表記は,「あるリストから別のリストを作る」ときに便利です.特に使わなくても困ることはないですが,場合によってはスマートに書けるので重宝されます.
48. 例外処理

下記のように変数が作られています.

a = 0
b = 5

この時,\frac{a}{b}\frac{b}{a}を出力してください.ただし,ゼロ割りが発生した時にはzero divisionを出力します.
例外処理を用いて書いてみると良いと思います.

期待する出力:0, zero division

解答

a = 0
b = 5

try:
    print(a / b)
except ZeroDivisionError:
    print('zero division')

try:
    print(b / a)
except ZeroDivisionError:
    print('zero division')
  • 例外処理は,try ~ exceptで表現されます.tryには行いたい処理を書いて,その処理を行う上で回避したいエラーがあれば,exceptに回避策を書きます.
  • pythonはゼロ割を検知するとZeroDivisionErrorを返す(raiseされる)ので,except ZeroDivisionError:となります.他にも,配列外参照ならIndexErrorがraiseされるので,except IndexError:となります.
49. ビット演算

変数a10を,変数b5を代入します.この時,ab論理和論理積排他的論理和を出力してください.出力形式は問いません.

期待する出力:15 0 15

解答

a = 10
b = 5
print(a|b, a&b, a^b)
  • ビット演算は,各ビットに対して演算が行われます.
  • 10進数 -> 2進数とする時,10 -> 1010, 5 -> 0101なので,例えば論理和を取ると1111となり,これは15です.
50. モジュールのインポート

mathモジュールをインポートして,\theta = \frac{\pi}{2}の下で,sin\theta^2 + cos\theta^2 = 1.0の値を出力してください.

期待する出力:1.0

解答

import math
theta = math.pi / 2
ans = math.sin(theta)**2 + math.cos(theta)**2
print(ans)
  • モジュールのインポートは,プログラムを書く上では欠かせません.
  • モジュールは山ほど存在し,用途によって使い分けます.有名なものだとnumpymatplotlibなどがあります.
演習1(forのネスト)

1から31までの整数を要素とするリスト1と,1から12までの整数を要素とするリスト2を作成します.リスト1とリスト2から値を1つずつ取ってきた時,1の位が一致する値が何組あるかを求めてください.例えば,111は,1の位が両方1なので,カウントに入ります.11311なども同様です.

期待する出力:38

解答

li1 = list(range(1, 32))
li2 = list(range(1, 13))
counter = 0
for elem1 in li1:
    for elem2 in li2:
        if elem1%10 == elem2%10:
            counter += 1
print(counter)
  • 2つのリストから抽出できる組を全て調べれば良いです.1の位が等しいかどうかは,10で割った余りを見れば判定できます.
  • for文は何重にでも重ねることができ,重ねることをネストすると呼ぶときもあります.
演習2(辞書の値ソート)

辞書が以下のように定義されています.

dic = {'two':324, 'four':830, 'three':493, 'one':172, 'five':1024}

この時,値で昇順ソートしたと考えた場合のキーの並びを出力してください.

期待する出力:['one', 'two', 'three', 'four', 'five']

解答

dic = {'two':324, 'four':830, 'three':493, 'one':172, 'five':1024}
items_list = list(dic.items())
sorted_items_list = sorted(items_list, key=lambda x:x[1])
ans = [elem[0] for elem in sorted_items_list]
print(ans)
  • この演習では,valuesのソート時に,keysの並びも変えるところが厄介です.items()で一旦タプルのリストにしてから,タプルの2つ目の値でソートするようにします.これにはkey=のパラメタを利用します.key=にはラムダ式を使って,各要素のどこに注目てソートするかを指定します.
演習3(num2freq)

リストが以下のように定義されています.

nums = [1,2,4,3,2,1,5,1]

このリストに対して,要素の出現数を格納した辞書num2freqを作成し,出力してください.これはnum2freq[要素] = 出現数となるような辞書で,例えばnum2freq[1] = 3です.

期待する出力:{1: 3, 2: 2, 4: 1, 3: 1, 5: 1}

解答

nums = [1,2,4,3,2,1,5,1]
num2freq = {}
for num in nums:
    num2freq[num] = num2freq.get(num, 0) + 1

print(num2freq)
  • 辞書を作成し,要素をキーとしたときの値を順次増やします.
演習4(word2freq)

今,文字列が以下のように与えられています.

doc = 'i bought an apple .\ni ate it .\nit is delicious .'

\nは改行記号なので,3つの文が3行に渡って書かれていることになります.
この文章中の単語を用いて,キーとして単語,値として出現数を持つような辞書word2freqを作成し,出力してください.ただし,改行記号は単語に含めないでください.
ヒント:改行記号でsplitしてから空白でsplitすれば,単語に分割できます.

期待する出力:{'i': 2, 'bought': 1, 'an': 1, 'apple': 1, '.': 3, 'ate': 1, 'it': 2, 'is': 1, 'delicious': 1}

解答

doc = 'i bought an apple .\ni ate it .\nit is delicious .'
word2freq = {}
sents = doc.split('\n')
for sent in sents:
    words = sent.split()
    for word in words:
        word2freq[word] = word2freq.get(word, 0) + 1

print(word2freq)
  • ヒントの通りsplitすれば,単語のリストが得られます.各単語をキーとして,対応する値を順次増やします.
演習5(Jaccard係数)

2つの集合A,Bの類似度を計算する方法として,Jaccard係数というものがあります.例えば,文章の類似度の指標として使われています.

Jaccard(A,B) = \frac{|A \cap B|}{|A \cup B|} = \frac{AとBの積集合の要素数}{AとBの和集合の要素数}

2つのリストが与えられている時,リストを集合と見なした時のJaccard係数の値を求めてください.

list1 = [12,23,34,45,56,67,78,89]
list2 = [21,32,43,45,65,67,78,98]

期待する出力:0.23076923076923078

解答

list1 = [12,23,34,45,56,67,78,89]
list2 = [21,32,43,45,65,67,78,98]

A = set(list1)
B = set(list2)
inter_set = A.intersection(B)
union_set = A.union(B)
print(len(inter_set) / len(union_set))
  • リストを集合に変換した後,Jaccard係数の計算式の通りに計算します.要素数len()で見れば良いです.