本記事について
競技プログラミングサイトの AtCoder にはプログラミング入門教材の「AtCoder Programming Guide for beginners (APG4b)」があります。プログラミング入門教材として非常に完成度が高く、競技プログラミングの主流言語である C++ が使われています。
そこで、本記事では APG4b を元に、それの Python 版を書きました。基本的には APG4b を読み進めて、Python 独自の部分は本記事を参考にして頂ければと思います。
大部分が APG4b を元にしているため、本記事が問題あるようでしたらすぐに削除します。
各節の見出しが本家へのリンクになっています。
節タイトルは本家に合わせているため、Pythonの用語と一部異なる部分もあります。
目次
1.00.はじめに
1.01.出力とコメント
1.02.プログラムの書き方とエラー
1.03.四則演算と優先順位
1.04.変数と型
1.05.実行順序と入力
1.06.if文・比較演算子・論理演算子
1.07.条件式の結果とbool型
1.08.変数のスコープ
1.09.複合代入演算子
1.10.while文
1.11.for文・break・continue
1.12.文字列(と文字)
1.13.リスト(配列)
1.14.標準ライブラリの組み込み関数(STLの関数)
1.15.関数
おわりに
1.00.はじめに
第1章について
第1章では、基本的な文法について説明します。
プログラミング言語
本家 APG4b では C++ というプログラミング言語を扱っています。この記事では Python というプログラミング言語を扱います。
プログラムの実行方法
手元に Python の環境構築をするのも良いですが、AtCoder のコードテストでも十分書くことができます。
問題
提出練習
本記事には Python 版のコードを載せますが、問題への提出は本家の提出欄を使用してください。提出欄は、本家のページの一番下にあります。
まずは、提出欄の「言語」を「Python (3.8.2)」に変更してください。
変更したら、次のコードをコピー&ペーストしてみましょう。
print("Hello, world!")
ペーストできたら、「提出」ボタンを押してください。
ページが切り替わり、結果欄が緑色の「AC」になっていれば提出成功です。
1.01.出力とコメント
キーポイント
- Python のコードは、処理内容を直接書くことができる
- main 関数を書く必要がない。書くこともできるが、競プロのような小規模なコードの際は書かなくても大丈夫
-
print("文字列")
で文字列を出力できる -
#
と書くことで、その行の#
以降がコメントになる
プログラムの基本形
次のプログラムは何もしないプログラムです。
つまり、C++ と違って main 関数等を書く必要がありません。処理内容を直接書くだけでプログラムが動きます。
main 関数を書くこともできますが、競技プログラミングのような小規模の場合は書かなくても大丈夫です。
出力
最初に提出したプログラムを見てみましょう。
このプログラムは「Hello, world!」という文字列を出力するプログラムです。
print("Hello, world!")
Hello, world!
print()
Python で文字列を出力するには print()
を使います。
出力する文字列を指定している部分は "Hello, world!"
の部分です。print()
の ()
内に書くことで、文字列を出力することができます。
Python プログラムの中で文字列を扱う場合、" "
で囲う必要があります。また、自動で文末に改行が行われます。
行の終わり
C++ では行末に ;
が必要ですが、Python では何も書く必要がありません。(一応書いても問題なく動きます)
別の文字列の出力
別の文字列を出力したい場合、次のように " "
の中身を変えます。
print("こんにちは世界")
こんにちは世界
複数の出力
出力を複数回行うこともできます。
print("a")
print("b")
print("c", "d")
a
b
c d
先ほども書いたように、Python の print()
では文末に自動で改行が行われます。そのため、a
の次の行に b
が出力されます。
次に、,
区切りで複数書くことで、c d
のように空白区切りで出力されます。
数値の出力
数値を出力するときは、" "
を使わずに、直接書くことでも出力できます。
print(2525)
2525
コメント
コメントはプログラムの動作を説明するためのメモ書きを残すためのもので、書いてもプログラムの動作に影響はありません。
Python におけるコメントの例を見てみましょう。
print("Hello, world!") # Hello, world! と表示
# ここもコメント
Hello, world!
#
と書くことで、その行の #
以降がコメントになります。
全角文字
Python では C++ と違い、プログラム中に「全角文字」が含まれていても基本的には問題なく動作します。
しかし、読みづらくなるため「半角文字」で書くことを推奨します。
問題
以下のリンク先に問題文が載っています。
EX1.コードテストと出力の練習
print("Hello, world!")
print("Hello, AtCoder!")
print("Hello, Python!")
Hello, world!
Hello, AtCoder!
Hello, Python!
解答例
必ず自分で問題に挑戦してみてから見てください。
解答例
1.02.プログラムの書き方とエラー
キーポイント
- Python はスペース・改行・インデントに意味がある
- Python には「PEP8」というコーディング規約がある
- Python はインタプリタ型言語であるため、コンパイルエラーは起こらない
プログラムの書き方
プログラム中のスペースと改行、およびインデントについて説明します。また、Python のコーディング規約である PEP8 についても説明します。
スペースと改行
Python では、スペースは省略することができますが、改行には意味があるため省略できません。
C++ では ;
が行の終わりを意味しますが、Python では改行が行の終わりを意味します。
インデント
C++ ではインデントは読みやすさのために行いますが、Python の場合はインデントにも意味があります。
後述の if 文を例に C++ と Python の違いを見てみましょう。
#include <bits/stdc++.h>
using namespace std;
int main() {
if (条件式) {
処理
}
}
#include <bits/stdc++.h>
using namespace std;
int main() {
if (条件式) {
処理
}
}
C++ の場合、上記のように { }
内でインデントを行っても行わなくても動作に違いはありません。
if 条件式:
処理
Python では { }
の代わりに :
とインデントを用いて if 文の中であることを表現するため、インデントが必須となります。
PEP8
PEP8 とは、Python のコーディング規約です。コーディング規約とは読みやすさのために定められたルールのことです。
PEP8 を守らなくてもプログラムは問題なく動作しますが、守ることで読みやすいプログラムを書くことができます。
すべてを紹介すると長くなるため、ここではそのうちのいくつかを紹介します。
- インデントは半角スペース4つ
- 1行の長さは最大79文字
- 余計なスペースは入れない
詳細は https://pep8-ja.readthedocs.io/ja/latest/ に書いてあります。
プログラムのエラー
基本的には本家 APG4b に書いてある通りですが、Python はインタプリタ型言語であるため、コンパイルエラーは起きません。
インタプリタ型言語とは、C++ のようにコンパイルを行わず、1文ずつ実行されていきます。そのため、文法の間違いがあった場合はコンパイルエラーではなく実行時エラーになります。
問題
以下のリンク先に問題文が載っています。
EX2.エラーの修正
print("いつも)
print("2525"
print(AtCoderくん)
File "./Main.py", line 1
print("いつも)
^
SyntaxError: EOL while scanning string literal
解答例
必ず自分で問題に挑戦してみてから見てください。
解答例
1.03.四則演算と優先順位
キーポイント
演算子 | 計算内容 |
---|---|
+ | 足し算 |
- | 引き算 |
* | 掛け算 |
/ | 割り算 |
// | 切り捨て割り算 |
% | 割った余り |
** | 冪乗 |
四則演算
Python プログラムで簡単な計算をする方法を見ていきましょう。
次のプログラムは上から順に、「足し算」「引き算」「掛け算」「割り算」「切り捨て割り算」を行っています。
print(1 + 1) # 2
print(3 - 4) # -1
print(2 * 3) # 6
print(7 / 3) # 2.3333333333333335
print(7 // 3) # 2
2
-1
6
2.3333333333333335
2
これらの記号 +
, -
, *
, /
のことを算術演算子といいます。
3 - 4
が -1
になっている通り、負の値も計算できます。
*
が掛け算で、 /
が「割り算」です。
Python では /
は普通の割り算で、結果は小数になります。小数点以下が切り捨てされる割り算は //
で行います。
また、 //
は常にマイナス無限大方向に丸められます。C++ の /
も切り捨て割り算ですが、C++ の /
は常に0方向に丸められるため、C++ の /
と Python の //
は違います。Python で常に0方向に丸めたいときは、int(a / b)
のように書きましょう。
print(10 // 3, -10 // 3)
print(int(10 / 3), int(-10 / 3))
3 -4
3 -3
剰余演算
%
は「割ったときの余り」を計算します。
print(7 % 3) # 1
print(4 % 5) # 4
1
4
$7 ÷ 3 = 2$ あまり $1$
$4 ÷ 5 = 0$ あまり $4$
となるため、このプログラムの出力は 1
と 4
になります。
冪乗演算
Python には冪乗の演算子も用意されています。冪乗とは、 $a ^ b$ と表される数です。
print(3 ** 4) # 81
print(25 ** 0.5) # 5.0
print(1.5 ** 2) # 2.25
81
5.0
2.25
上記のように、 a ** b
で $a ^ b$ が計算できます。また、 25 ** 0.5
や 1.5 ** 2
のように小数の計算もできます。
演算子の優先順位
四則演算の優先順位は C++ と同じため、本家を参考にしてください。
問題
以下のリンク先に問題文が載っています。
EX3.計算問題
print(""" ここに式を書く """)
解答例
必ず自分で問題に挑戦してみてから見てください。
解答例
1.04.変数と型
キーポイント
- 変数はメモ
-
=
は代入 - 「データの種類」のことを型という
型 | 書き込むデータの種類 |
---|---|
int | 整数 |
float | 小数 |
str | 文字列 |
変数
変数という機能について見ていきましょう。変数は「メモ」だと考えてください。
例を見てみましょう。
name = 10
print(name) # 10
print(name + 2) # 10 + 2 → 12
print(name * 3) # 10 * 3 → 30
10
12
30
宣言と代入
Python の場合、宣言と代入は同時に行います。宣言が必要ないと言った方が正確かもしれません。
name = 10
この部分で、「name」という変数を宣言して、その中に 10
を代入しています。
=
の記号は「代入(書き込み)」の意味であって、「等しい」という意味ではないことに注意してください。
「型」や「値」についての説明は本家を参照してください。
C++ の場合は int
と書いて、変数の型が「整数」であることを明示する必要がありますが、Python の場合は代入する 10
が整数であるため、自動で name
の型を int にしてくれます。
読み込み
プログラムの最後の3行で変数にメモした値を読み込んで出力しています。
print(name) # 10
print(name + 2) # 10 + 2 → 12
print(name * 3) # 10 * 3 → 30
変数はコピーされる
変数1 = 変数2
と書いた場合、変数の値そのものがコピーされます。
その後にどちらかの変数の値が変更されても、もう片方の変数は影響を受けません。
a = 10
b = a
a = 5
print(a) # 5
print(b) # 10
5
10
変数 b
が 10 のままであることに注意してください。
処理内容は本家の方にわかりやすく図で説明されています。Python の場合は宣言と代入が同時に行われるため、b
の宣言は b = a
の部分で行われます。
変数を同時に代入
変数の代入時に ,
を間に入れることで、1行で複数の変数の代入が行えます。
a, b = 10, 5
print(a)
print(b)
10
5
上のプログラムは次のように書いた場合と同じ意味になります。
a = 10
b = 5
変数名のルール
変数名は基本的に自由につけることができますが、一部の名前を変数名にしようとするとエラーになります。
利用できない変数名
以下の条件に該当する名前は変数名にできません。
- 数字で始まる名前
-
_
以外の記号が使われている名前 - キーワード(Python が使っている一部の単語)
以下は変数名にできない名前の例です。本家の例で使われている int
は、Python では変数名として使うことができます(……推奨はしませんが)。
100hello = 10 # 数字で始まる名前にはできない
na+me = "AtCoder" # 変数名に+を使うことはできない
not = 100 # not はキーワードなので変数名にできない
以下のような名前は変数名にできます。
hello10 = 10 # 2文字目以降は数字にできる
hello_world = "Hello, world" # _ は変数名に使える
変数1 = 1 # 漢字
へんすう2 = 2 # ひらがな
Python の場合は C++ と違って、漢字やひらがなも変数名に使うことができます。
Python のキーワードについては、検索すると一覧が出てきます。
型
int
以外にも Python には様々な型があります。ここでは重要な3つの型だけを紹介します。
C++ では小数は double
ですが、Python では float
になります。同様に文字列は str
です。
型 | 書き込むデータの種類 |
---|---|
int | 整数 |
float | 小数(実数) |
str | 文字列 |
i = 10 # 10 は整数
f = 0.5 # 0.5 は小数
s = "Hello" # "Hello" は文字列
print(i, type(i)) # type(変数) で変数の型がわかる
print(f, type(f))
print(s, type(s))
10 <class 'int'>
0.5 <class 'float'>
Hello <class 'str'>
異なる型同士の計算
異なる型同士の計算では型変換が行われます。
例えば、int 型と float 型の計算結果は float 型になります。
ただし、変換できない型同士の計算はエラーになります。
i = 30
d = 1.5
s = "Hello"
print(i + d, type(i + d)) # 31.5
print(i * d, type(i * d)) # 45.0
"""
以下の処理はエラー
print(s + i) # str型とint型の足し算
print(s + d) # str型とfloat型の足し算
"""
31.5 <class 'float'>
45.0 <class 'float'>
なお、Python の場合は str型 * int型
の計算は可能です。
i = 5
s = "Hello"
print(s * i) # "Hello" * 5 → ???
上のプログラムの結果はどうなるでしょうか。実行結果を見てみましょう。
HelloHelloHelloHelloHello
"Hello"
が5回繰り返された文字列になります。
異なる型同士の代入
Python の場合、変数の型は中に何が入っているかによって決まります。よって、次のプログラムは正常に動作します。
i = 10
s = "Hello"
i = s
print(i)
print(type(i))
Hello
<class 'str'>
問題
以下のリンク先に問題文が載っています。
EX4.◯年は何秒?
# 1年の秒数
seconds = 365 * 24 * 60 * 60
# 以下のコメント """ """ を消して追記する
print(""" 1年は何秒か """)
print(""" 2年は何秒か """)
print(""" 5年は何秒か """)
print(""" 10年は何秒か """)
解答例
必ず自分で問題に挑戦してみてから見てください。
解答例
1.05.実行順序と入力
キーポイント
- プログラムは上から下へ順番に実行される
-
変数 = input()
で入力を受け取ることができる - スペースと改行で区切られて入力される
プログラムの実行順序
基本的にプログラムは上から下へ順番に実行されます。
次のプログラムを見てください。
name = 10
print(name) # 10
name = 5
print(name) # 5
10
5
基本的な構造は本家と同様なので、実行の様子については本家のスライドを参照してください。
入力
プログラムの実行時にデータの入力を受け取る方法を見ていきましょう。
「入力機能」を使うことにより、プログラムを書き換えなくても様々な計算を行えるようになります。
入力を受け取るには input()
を使います。
次のプログラムは、入力として受け取った数値を10倍にして出力するプログラムです。
a = int(input())
print(a * 10)
5
50
input()
は1行の入力を文字列として受け取ります。そのため、int 型として受け取るためには int()
によって int 型に変換してあげる必要があります。
a = input()
print(a, type(a))
a = int(a) # int型に変換
print(a, type(a))
5
5 <class 'str'>
5 <class 'int'>
整数以外のデータの入力
整数以外のデータを受け取りたい時は、同様に必要な型に変換する必要があります。
text = input()
f = float(input())
print(text, f)
Hello
1.5
Hello 1.5
空白区切りの入力
前述のように、input()
は1行の入力を文字列として受け取ります。
a = input()
print(a)
print(type(a))
10 20 30
10 20 30
<class 'str'>
そのため、空白区切りの入力をただ受け取ると、上のように変数 a
に "10 20 30"
という文字列として代入されてしまいます。
空白で分割
そこで、input()
の後ろに .split()
をつけて文字列を分解する必要があります。
a, b, c = input().split()
print(a)
print(type(a))
10 20 30
10
<class 'str'>
こうすることで "10 20 30"
が空白区切りで分割されて、"10"
, "20"
, "30"
の3つにすることができました。
整数に変換
あとは、これまでと同様に int()
を使って整数に変換してあげれば、空白区切りの入力を整数として受け取ることができます。
a, b, c = input().split()
a = int(a)
b = int(b)
c = int(c)
print(a)
print(type(a))
10 20 30
10
<class 'int'>
上のプログラムでは int 型への変換を変数の数だけ毎回書きましたが、これを1行で書くこともできます。
a, b, c = map(int, input().split())
print(a)
print(type(a))
10 20 30
10
<class 'int'>
map(型, input().split())
と書くことで、分割された全ての文字列を同時に指定した型に変換することができます。
複数行の入力
input()
は1行の入力を受け取るものなので、入力が複数行ある場合はその行数分書く必要があります。
s = input()
a = int(input())
print(s, a)
Hello
10
Hello 10
問題
以下のリンク先に問題文が載っています。
EX5.A足すB問題
# ここにプログラムを追記
解答例
必ず自分で問題に挑戦してみてから見てください。
解答例
1.06.if文・比較演算子・論理演算子
キーポイント
- if文を使うと「ある条件が正しいときだけ処理をする」というプログラムを書ける
- else句を使うと「条件が正しくなかったとき」の処理を書ける
if 条件式1:
処理1
elif 条件式2:
処理2
else:
処理3
- 比較演算子
演算子 | 意味 |
---|---|
x == y |
x と y は等しい |
x != y |
x と y は等しくない |
x > y |
x は y より大きい |
x < y |
x は y より小さい |
x >= y |
x は y 以上 |
x <= y |
x は y 以下 |
- 論理演算子
演算子 | 意味 | 真になるとき |
---|---|---|
not 条件式 |
条件式の結果の反転 | 条件式が偽 |
条件式1 and 条件式2 |
条件式1が真 かつ 条件式2が真 | 条件式1と条件式のどちらも真 |
条件式 or 条件式2 |
条件式1が真 または 条件式2が真 | 条件式1と条件式2の少なくとも片方が真 |
if文
if文を使うと、ある条件が正しいときだけ処理をするというプログラムが書けるようになります。
書き方は次のようになります。
if 条件式:
処理
条件式が正しいとき、:
以降のインデントが1つ下がった部分の処理が実行され、条件式が正しくないとき、処理は飛ばされます。
次の例では、入力の値が10より小さければ「xは10より小さい」と出力した後「終了」と出力します。また、入力の値が10より小さくなければ「終了」とだけ出力されます。
x = int(input())
if x < 10:
print("xは10より小さい")
print("終了")
5
xは10より小さい
終了
15
終了
この例では、まず変数 x に整数のデータを入力しています。
x = int(input())
重要なのはその後です。
if x < 10:
print("xは10より小さい")
この部分は、「もし x < 10
(xが10より小さい)なら、 xは10より小さい
と出力する」という意味になります。
最後に print("終了")
を実行して 終了
と出力し、プログラムは終了します。
xが10より小さくない場合は、
print("xは10より小さい")
の処理は飛ばされます。そのため、2つ目の実行例では 終了
とだけ出力されています。
if文のように、何かの条件で処理が実行されることを条件分岐といいます。
また、「条件式が正しい」ことを条件式が真、「条件式が正しくない」ことを条件式が偽といいます。
比較演算子
Python の比較演算子は C++ と同じため、この項は本家を参照してください。
演算子 | 意味 |
---|---|
x == y |
x と y は等しい |
x != y |
x と y は等しくない |
x > y |
x は y より大きい |
x < y |
x は y より小さい |
x >= y |
x は y 以上 |
x <= y |
x は y 以下 |
次のプログラムは、入力された整数値がどんな条件を満たしているかを出力するプログラムです。
x = int(input())
if x < 10:
print("xは10より小さい")
if x >= 20:
print("xは20以上")
if x == 5:
print("xは5")
if x != 100:
print("xは100ではない")
print("終了")
5
xは10より小さい
xは5
xは100ではない
終了
100
xは20以上
終了
論理演算子
条件式の中にはもっと複雑な条件を書くこともできます。そのためには論理演算子を使います。
演算子 | 意味 | 真になるとき |
---|---|---|
not 条件式 |
条件式の結果の反転 | 条件式が偽 |
条件式1 and 条件式2 |
条件式1が真 かつ 条件式2が真 | 条件式1と条件式のどちらも真 |
条件式 or 条件式2 |
条件式1が真 または 条件式2が真 | 条件式1と条件式2の少なくとも片方が真 |
x, y = map(int, input().split())
if not x == y:
print("xとyは等しくない")
if x == 10 and y == 10:
print("xとyは10")
if x == 0 or y == 0:
print("xかyは0")
print("終了")
2 3
xとyは等しくない
終了
10 10
xとyは10
終了
0 8
xとyは等しくない
xかyは0
終了
「前の条件が真でないとき」の処理
else句
else句は、if文の後に書くことで、「if文の条件が偽のとき」に処理を行えるようになります。
書き方は次のようになります。
if 条件式1:
処理1
else:
処理2
次のプログラムは、入力の値が10より小さければ「xは10より小さい」と出力し、そうでなければ「xは10より小さくない」と出力します。
x = int(input())
if x < 10:
print("xは10より小さい")
else:
print("xは10より小さくない")
5
xは10より小さい
15
xは10より小さくない
elif
elif
では、「『前のif文の条件が偽』かつ『elifの条件が真』」のときに処理が行われます。
書き方は次のようになります。
if 条件式1:
処理1
elif 条件式2:
処理2
処理2が実行されるのは、「条件式1が偽 かつ 条件式2が真」のときになります。
例を見てみましょう。
x = int(input())
if x < 10:
print("xは10より小さい")
elif x > 20:
print("xは10より小さくなくて、20より大きい")
elif x == 15:
print("xは10より小さくなくて、20より大きくなくて、15である")
else:
print("xは10より小さくなくて、20より大きくなくて、15でもない")
5
xは10より小さい
30
xは10より小さくなくて、20より大きい
15
xは10より小さくなくて、20より大きくなくて、15である
13
xは10より小さくなくて、20より大きくなくて、15でもない
この例のように、elif の後に続けて elif や else を書くこともできます。
問題
以下のリンク先に問題文が載っています。
EX6.電卓をつくろう
a, op, b = input().split()
a = int(a)
b = int(b)
if op == "+":
print(a + b)
# ここにプログラムを追記
解答例
必ず自分で問題に挑戦してみてから見てください。
解答例
1.07.条件式の結果とbool型
キーポイント
- 条件式の結果は真のときに
True
に、偽のときにFalse
になる - int型では、
True
を1
で、False
を0
で表す -
bool型は
True
とFalse
だけが入る型
int型の表現 | bool型の表現 | |
---|---|---|
真 | 1 | True |
偽 | 0 | False |
条件式の結果
Python では、真のことを True
で表現し、偽のことを False
で表現します。C++ と違って先頭が大文字なことに注意してください。
条件式の「計算結果」も真のときは True
、偽のときは False
になります。
次のプログラムは条件式の結果をそのまま出力し、真のときと偽のときでどのような値を取るか確認しています。
print(5 < 10)
print(5 > 10)
True
False
出力を見てみると、条件が真のときは True
、偽のときは False
になっていることがわかります。
TrueとFalse
Python の場合、通常は真と偽を True
と False
で表すのでこのタイトルは正しくない気もしますが、本家に合わせます。
条件式の部分に直接 True
や False
を書くこともできます。次のプログラムはその例です。
# Trueは真を表すので、helloと出力される
if True:
print("hello")
# Falseは偽を表すのでこのifの中は実行されない
if False:
print("world")
hello
また、int型においては True
を 1
、False
を 0
で表します。
print(int(True))
print(int(False))
1
0
bool型
bool型というデータ型があります。この型の変数には True
または False
だけが入ります。
x = int(input())
a = True
b = x < 10 # xが10未満のときTrue そうでないときFalseになる
c = False
if a and b:
print("hello")
if c:
print("world")
3
hello
このように、条件式の結果など、真偽のデータを変数で扱いたい場合は bool 型を使います。
いままで if 条件式
と書いていましたが、基本的には if bool型の値
ということになります。
ここまでの話をまとめたのが次の表です。
int型の表現 | bool型の表現 | |
---|---|---|
真 | 1 | True |
偽 | 0 | False |
bool型を使う場面
本家を参照してください。
問題
以下のリンク先に問題文が載っています。
EX7.bool値パズル
# 変数a, b, cにTrueまたはFalseを代入してAtCoderと出力されるようにする
a = # True または False
b = # True または False
c = # True または False
# ここから先は変更しないこと
if a:
print("At", end="") # end="" と書くと末尾改行がされなくなる
else:
print("Yo", end="")
if (not a) and b:
print("Bo", end="")
elif (not b) and c:
print("Co", end="")
if a and b and c:
print("foo!")
elif True and False:
print("yeah!")
elif (not a) or c:
print("der")
解答例
必ず自分で問題に挑戦してみてから見てください。
解答例
1.08.変数のスコープ
キーポイント
- インデントが共通の部分をブロックという
- 変数が使える範囲のことをスコープという
- 通常、変数のスコープは「変数が宣言されてからそのブロックが終わるまで」
- Pythonの場合、if文などではスコープが作られず、ブロック外でも使うことができる
変数のスコープ
今までif文の後ろに :
を書いて以下の行でインデントを行なってきました。このインデントがある部分のことをブロックといいます。
本家には「
あるブロックの中で宣言した変数は、それより内側のブロックでしか使えないというルールがあります。そして、その変数が使える範囲のことをスコープといいます。
」と書かれています。
Python の場合 C++ とは異なっていて、if文などの場合はスコープが作られず、ブロック内で宣言した変数をブロック外でも使うことができます。
具体例を見てみましょう。
x = 5
if x == 5:
y = 10
print(x + y)
print(x)
print(y)
15
5
10
これは本家に載っているプログラムと同内容のものです。
本家では C++ を扱っているため、これはエラーが出る例として載っていますが、Python では上のようにエラーは発生せず、正常に動作します。
スコープについての詳しい話は本家を参照してください。
問題
以下のリンク先に問題文が載っています。
EX8.たこ焼きセット
p = int(input())
# パターン1
if p == 1:
price = int(input())
# パターン2
if p == 2:
text = input()
price = int(input())
n = int(input())
print(text + "!")
print(price * n)
解答例
必ず自分で問題に挑戦してみてから見てください。
解答例
1.09.複合代入演算子
キーポイント
-
x = x + y
はx += y
のように短く書ける - Python にはインクリメントもデクリメントもない
複合代入演算子
x = x + 1
のように、同じ変数名が2回現れる代入文では、複合代入演算子を使うとより短く書くことができます。
次のプログラムは、変数 x に (1 + 2)
を足して出力するだけのプログラムです。
x = 5
x += 1 + 2
print(x) # 8
8
x += 1 + 2
は、
x = x + (1 + 2)
と同じ意味になります。
+=以外の複合代入演算子
他の算術演算子についても同様のことができます。
a = 5
a -= 2
print(a) # 3
b = 3
b *= 1 + 2
print(b) # 9
c = 5
c /= 2
print(c) # 2.5
d = 5
d //= 2
print(d) # 2
e = 5
e %= 2
print(e) # 1
f = 3
f **= 4
print(f) # 81
3
9
2.5
2
1
81
インクリメントとデクリメント
C++ にはインクリメントとデクリメントがありますが、Python にはありません。
インクリメントについて知りたい場合は本家を参照してください。
問題
以下のリンク先に問題文が載っています。
EX9.複合代入演算子を使おう
x, a, b = map(int, input().split())
# 1.の出力
x += 1
print(x)
# ここにプログラムを追記
解答例
必ず自分で問題に挑戦してみてから見てください。
解答例
1.10.while文
キーポイント
- while文を使うと繰り返し処理ができる
- 条件式が真のとき処理を繰り返す
while 条件式:
処理
- 「$N$回カウントする」というプログラムを書く場合、「カウンタ変数を0からはじめ、カウンタ変数が$N$より小さいときにループ」という形式で書く
i = 0 # カウンタ変数
while i < N:
処理
i += 1
while文
while文を使うと、プログラムの機能の中でも非常に重要な「繰り返し処理」(ループ処理)を行うことができます。
無限ループ
次のプログラムは、「"Hello"
と出力して改行した後、"AtCoder"
と出力する処理」を無限に繰り返すプログラムです。
while True:
print("Hello")
print("AtCoder")
Hello
AtCoder
Hello
AtCoder
Hello
AtCoder
Hello
AtCoder
Hello
AtCoder
...(無限に続く)
while文は次のように書き、条件式が真のとき処理を繰り返し続けます。
while 条件式:
処理
先のプログラムでは条件式の部分に True
と書いているため、無限に処理を繰り返し続けます。
このように、無限に繰り返し続けることを無限ループと言います。
1つずつカウントする
次のプログラムは、1から順に整数を出力し続けます。
i = 1
while True:
print(i)
i += 1 # ループのたびに1増やす
1
2
3
4
5
6
7
8
...(無限に1ずつ増えていく)
ループ回数の指定
1ずつカウントするプログラムを「1から5までの数を出力するプログラム」に変える場合、次のようにします。
i = 1
# i が 5 以下の間だけループ
while i <= 5:
print(i)
i += 1
1
2
3
4
5
カウンタ変数は0からN未満まで
5回 "Hello"
と出力されるプログラムを考えます。
まず一般的でない書き方(やめておいた方が良い書き方)を紹介し、次に一般的な書き方(推奨される書き方)を紹介します。
一般的でない書き方
# i を 1 からはじめる
i = 1
# i が 5 以下の間だけループ
while i <= 5:
print("Hello")
i += 1
Hello
Hello
Hello
Hello
Hello
「$N$回処理をする」というプログラムをwhile文で書く場合、今までは「i
を1からはじめ、$N$以下の間ループする」という形式で書いてきました。
i = 1
while i <= N:
処理
i += 1
この形式は一見わかりやすいと感じるかもしれません。
しかし、この書き方はあまり一般的ではなく、次のように書いた方がいいです。
一般的な書き方
# i を 0 からはじめる
i = 0
# i が 5 未満の間だけループ
while i < 5:
print("Hello")
i += 1
Hello
Hello
Hello
Hello
Hello
「$N$回処理する」というプログラムを書く場合、次のような**「i
を0からはじめ、i
が$N$より小さいときにループする」という形式で書くのが一般的**です。
i = 0
while i < N:
処理
i += 1
最初は分かりづらく感じるかもしれませんが、こう書いた方がプログラムをシンプルに書けることが後々増えてくるので、慣れるようにしましょう。
なお、このプログラムの変数 i
のように「何度目のループか」を管理する変数のことをカウンタ変数と呼ぶことがあります。カウンタ変数は基本的に i
を使い、i
が使えない場合はj
, k
, l
, ...と名前をつけていくのが一般的です。
応用例
$N$人の合計点を求めるプログラムを作ってみましょう。
次のプログラムは「入力の個数$N$」と「点数を表す$N$個の整数」を入力で受け取り、点数の合計を出力します。
n = int(input())
sum = 0 # 合計点を表す変数
i = 0 # カウンタ変数
while i < n:
x = int(input())
sum += x
i += 1
print(sum)
3
1
10
100
111
合計点を表す変数 sum
を作っておき、ループするたびに入力変数 x
に入れ、sum
に足しています。
本家の方に処理内容を解説したスライドがあります。
問題
以下のリンク先に問題文が載っています。
EX10.棒グラフの出力
print()
だけだと末尾に自動で改行が入ってしまうため、print(出力内容, end="")
とすることで末尾改行を行わないことができます。
a, b = map(int, input().split())
# ここにプログラムを追記
解答例
必ず自分で問題に挑戦してみてから見てください。
解答例
1.11.for文・break・continue
キーポイント
- for文は繰り返し処理でよくあるパターンをwhile文より短く書くための構文
- 列の中身が先頭から順にカウンタ変数に代入される
for カウンタ変数 in 列:
処理
- $N$回の繰り返し処理は次のfor文で書くのが一般的
for i in range(N):
処理
- breakを使うとループを途中で抜けられる
- continueを使うと後の処理を飛ばして次のループへ行ける
for文
for文は「$N$回処理する」というような繰り返し処理でよくあるパターンをwhile文より短く書くための構文です。
3回繰り返すプログラムをwhile文とfor文で書くと次のようになります。
j = 0
while j < 3:
print("Hello while:", j)
j += 1
for i in range(3):
print("Hello for:", i)
Hello while: 0
Hello while: 1
Hello while: 2
Hello for: 0
Hello for: 1
Hello for: 2
for文は次のように書きます。
for カウンタ変数 in 列:
処理
列について詳しくは後の節で解説しますが、[3, 1, 4, 1, 5]
のような数列(リスト)や、"abcdef"
のような文字列があります。
次のプログラムを見てみましょう。
for i in [3, 1, 4, 1, 5]:
print("i:", i)
i: 3
i: 1
i: 4
i: 1
i: 5
リスト [3, 1, 4, 1, 5]
の中身が先頭から順に取り出されて、i
に代入されているのがわかります。
N回の繰り返し処理
「$N$回処理をする」というような繰り返し処理をしたいときは、range()
を使うと楽です。range(a, b)
と書くことで、[a, a+1, a+2, ..., b-1]
の数列が生成されます。
for i in range(0, 5): # [0, 1, 2, 3, 4]
print(i)
0
1
2
3
4
range(a, b)
の a
は0のときに省略することができ、 range(b)
と書くことができます。よって、次の2つの書き方は同じ意味になります。
for i in range(0, 5):
print(i)
for i in range(5):
print(i)
0
1
2
3
4
0
1
2
3
4
つまり、「$N$回の繰り返し処理」を書きたいときは次のように書けば良いです。とりあえずは簡単なこの書き方を覚えるところから始めましょう。
for i in range(N):
処理
for文を使うときのコツ
「$N$回の繰り返し処理」のfor文を使うときは、「列の先頭から順にカウンタ変数に代入される」という細かい動作を考えないようにしましょう。
よりおおざっぱに、for文は $i$ が1ずつ増えながら$N$回処理を繰り返す機能と考えた方が、for文を使うプログラムを書きやすくなります。
breakとcontinue
while文とfor文を制御する命令として、breakとcontinueがあります。
break
breakはループを途中で抜けるための命令です。
breakを使ったプログラムの例です。
# breakがなければこのループは i == 4 まで繰り返す
for i in range(5):
if i == 3:
print("ぬける")
break # i == 3 の時点でループから抜ける
print(i)
print("終了")
0
1
2
ぬける
終了
if文で i == 3
が真になったとき、break
の命令を実行することでforループを抜け、終了
と表示しています。
continue
continueは後の処理を飛ばして次のループへ行くための命令です。
continueを使ったプログラムの例です。
for i in range(5):
if i == 3:
print("とばす")
continue # i == 3 のとき これより後の処理を飛ばす
print(i)
print("終了")
0
1
2
とばす
4
終了
上のプログラムでは、if文で i == 3
が真になったとき、 continue
の命令を実行することでcontinueより下の部分を飛ばし、次のループに入ります。
問題
以下のリンク先に問題文が載っています。
EX11.電卓をつくろう2
次のように print("{}".format(変数))
と書くことで、 {}
の部分に変数の中身が埋め込まれます。
a = 1
b = "Hello"
print("{}:{}".format(a, b)) # 1つ目の{}にa 2つ目の{}にb
1:Hello
以下が問題のサンプルプログラムです。
n = int(input())
a = int(input())
# ここにプログラムを追記
解答例
必ず自分で問題に挑戦してみてから見てください。
解答例
1.12.文字列(と文字)
キーポイント
- Pythonでは文字列も文字もstr型で扱う
-
len(文字列変数)
で文字列の長さを取得できる -
文字列変数[i]
で $i$ 文字目にアクセスできる -
文字列変数[i]
のi
を添字という - 添字は0から始まる
- 添字の値が正しい範囲内に無いとエラーになる
文字列(str型)
abc
や hello
のように、文字が順番に並んでいるもののことを文字列といいます。
C++ では文字列と文字(長さが1)を区別しますが、Python では区別せず、両方とも文字列(str型)として扱います。
str1 = input()
str2 = ", world!"
print(str1 + str2)
Hello
Hello, world!
文字列の長さ
文字列の長さ(文字数)は len(文字列変数)
で取得できます。
s = "Hello"
print(len(s))
5
i 番目の文字
次のように書くと $i$ 文字目が取得できます。
文字列[i]
この i
のことを添字と言います。
添字は0から始まる
添字は0から始まることに注意しましょう。
s = "hello"
print(s[0]) # h
print(s[4]) # o
h
o
s[0]
で1文字目、s[4]
で5文字目を取得しています。
"hello"
という文字列の場合、添字と文字の対応は次の表の通りです。
添字 | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
文字 | h | e | l | l | o |
ループのカウンタ変数を0から始めるのと同じように、添字が0から始まることにも慣れていきましょう。
応用
ループ構文との組み合わせ
文字列はループ構文と組み合わせることで様々な処理が記述できるようになります。
次のプログラムでは、入力された文字に何文字 O
が含まれているかを数えています。
s = input()
count = 0
for i in range(len(s)):
if s[i] == "O":
count += 1
print(count)
LOOOOL
4
また Python では次のように書くこともできます。for文は列の先頭から順に見ていくため文字列にも対応しており、文字列の場合は先頭の文字から1文字ずつ順番に見ていきます。
s = input()
count = 0
for i in s:
if i == "O":
count += 1
print(count)
LOOOOL
4
注意点
範囲外エラー
添字の値が正しい範囲内に無いと実行時エラーになります。
次のプログラムは hello
という5文字の文字列(有効な添字は 0
〜 4
)に対して、 [10]
で存在しない文字数目にアクセスしようとしているため、エラーが発生します。
x = "hello"
print(x[10])
Traceback (most recent call last):
File "./Main.py", line 2, in <module>
print(x[10])
IndexError: string index out of range
256
添字が範囲外のときのエラーでは、4行目で "string index out of range"(範囲外)
というエラーメッセージが表示されることが特徴です。
全角文字の扱い
Python では C++ と違って全角文字が扱えます。
s = "こんにちは"
print(s[0])
print(s[2])
こ
に
問題
以下のリンク先に問題文が載っています。
EX12.足したり引いたり
s = input()
# ここにプログラムを追記
解答例
必ず自分で問題に挑戦してみてから見てください。
解答例
1.13.リスト(配列)
キーポイント
- Python では配列ではなくリストを使う
- リストは様々なデータの列を扱うことができる機能
-
リスト変数名 = [要素1, 要素2, ...]
でリストを作成できる -
リスト変数[i]
で $i$ 番目の要素にアクセスできる -
len(リスト変数)
でリストの要素数を取得できる - リストとfor文を組み合わせると、大量のデータを扱うプログラムを簡潔に書ける
- リストの添字のルールは文字列と同じ
リストと文字列
文字列は「文字の列」を扱うための機能でした。
リストは文字だけでなく、様々なデータの列を扱うことのできる非常に重要な機能です。
C++ では配列(vector)を扱いますが、Python ではリスト(list)を扱います。
主な違いは次の通りです。
違い | |
---|---|
C++ の vector | 1つの配列に入れられるのは1つの型のみ |
Python の list | 異なる型のデータを1つのリストに入れられる |
文字列とリストは使い方もある程度同じです。
次のプログラムは、「"a"
, "b"
, "c"
, "d"
」という文字の列と、「25
, 100
, 64
」という整数の列を扱っています。
# 文字列
s = "abcd" # "a", "b", "c", "d" という文字の列を入力
print(s[0]) # 1つ目である "a" を出力
print(len(s)) # 文字列の長さである 4 を出力
# リスト
a = [25, 100, 64] # 25, 100, 64 という整数(int)の列を代入
print(a[0]) # 1つ目である 25 を出力
print(len(a)) # リストの長さである 3 を出力
a
4
25
3
リスト変数の生成
リスト変数は次のように生成します。
リスト変数名 = [要素1, 要素2, ...]
リストが持つデータの1つ1つのことを要素と呼びます。
a = [25, 100, 64]
と書いた場合、「25, 100, 64」というデータ列がリスト変数 a
に代入されています。
i 番目の要素
文字列と同様に、リストも [i]
を使って $i$ 番目の要素へアクセスできます。
リスト変数[i]
リストでも添字は0から始まります。
a = [25, 100, 64]
というリスト変数 a
の場合、添字の値と文字の対応表は次の通りです。
添字 | 0 | 1 | 2 |
---|---|---|---|
要素 | 25 | 100 | 64 |
リストの要素数
文字列と同様に、リストも len()
を使って要素数(長さ)を取得できます。
len(リスト変数)
a = [25, 100, 64]
というリスト変数 a
の場合、len(a)
の値は 3
になります。
リストへの入力
空白区切りの入力
空白区切りの入力の受け取りで input().split()
を扱いましたが、実はこれはリストとして受け取っています。
a = input().split()
print(a)
3 1 4 1 5
['3', '1', '4', '1', '5']
これだけだとstr型として受け取ってしまうので、int型で受け取るには map()
を使います。 map()
を使うことで、リストの全ての要素に対して型の変換を行うことができます。
a = list(map(int, input().split()))
print(a)
3 1 4 1 5
[3, 1, 4, 1, 5]
map()
だけだとmapオブジェクトになってしまうため、list()
でくくることでリストに直しています。
改行区切りの入力
次のような改行区切りの入力を受け取りたいときもあります。
3
1
4
1
5
その場合は、まず空のリストを作ってから順番に要素を追加していきます。
空のリストは要素を何も書かないことで作ることができます。
リスト変数 = [] # 空のリスト
リストに要素を追加するには、.append(追加する要素)
を使います。
リスト変数.append(追加する要素)
これらとfor文を組み合わせることで、改行区切りの入力を受け取ることができます。
n = int(input()) # 入力の1行目が要素数の場合
a = []
for i in range(n):
a.append(int(input()))
print(a)
5
3
1
4
1
5
[3, 1, 4, 1, 5]
リストの使い所
リストとfor文を組み合わせると、大量のデータを扱うプログラムを書くことができます。
次の例題を見て下さい。
例題
問題文は本家を参照してください。
解答例
$N$ が小さい場合、リストを使わずにint型の変数だけでこの問題を解くことも可能です。
しかし、$N$ が大きい場合はリストを使わずに書くのは非常に大変になります。
例えば $N = 1000$ だったとき、変数を1000個宣言しなければなりません。
リストとfor文を使えば、$N$ の大きさに関わらず簡潔に処理を書くことができます。
n = int(input())
# 数学と英語の点数データを受け取る
math = list(map(int, input().split()))
english = list(map(int, input().split()))
# 合計点を出力
for i in range(n):
print(math[i] + english[i])
注意点
文字列と同様に、リストにも添字の値が正しい範囲内に無いとエラーになります。
次のプログラムは [1, 2, 3]
という3要素のリスト(有効な添字は 0
〜 2
)に対し、[10]
で存在しない要素にアクセスしようとしているため、エラーが発生します。
a = [1, 2, 3]
print(a[10])
Traceback (most recent call last):
File "./Main.py", line 2, in <module>
print(a[10])
IndexError: list index out of range
256
文字列と同様に、4行目で "IndexError: list index out of range"(範囲外)
というエラーメッセージが表示されます。
細かい話
細かい話なので、飛ばして問題を解いても良いです。
後ろからの添字
Python では、添字にマイナスを使うことで後ろから見ることができます。
a = [1, 2, 3, 4, 5]
print(a[-1]) # 後ろから1番目
print(a[-3]) # 後ろから3番目
5
3
後ろから見る場合は、一番後ろを -1
として、後ろから2番目が -2
、3番目が -3
と数えます。
スライス
Python のリストでは、スライスと呼ばれるリストの一部分を取得する操作があります。
スライスは次のようにして使います。
リスト変数[始点の添字:終点の添字]
始点の添字から始め、終点の添字の1つ手前までがリストとして取得されます。
a = [1, 2, 3, 4, 5]
というリスト変数 a
の場合、 a[1:3]
は [2, 3]
になります。添字を省略すると、始点の場合は先頭から、終点の場合は一番後ろまでを取得します。
また、スライスはステップ(いくつおきに見るか)を指定することもできます。
リスト変数[始点の添字:終点の添字:ステップ]
例えばステップに 2
を指定すると、要素を1つ飛ばしで取得することができます。
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[::2]) # 先頭から1つ飛ばし → 偶数番目
print(a[1::2]) # 奇数番目
[0, 2, 4, 6, 8]
[1, 3, 5, 7, 9]
問題
以下のリンク先に問題文が載っています。
EX13.平均点との差
n = int(input())
# ここにプログラムを追記
解答例
必ず自分で問題に挑戦してみてから見てください。
解答例
1.14.標準ライブラリの組み込み関数(STLの関数)
キーポイント
- 関数を使うとプログラムのまとまった機能を簡単に使うことができる
- Python で用意されている関数等がまとまっているもののことを標準ライブラリという
- 標準ライブラリ内に用意されている関数のことを組み込み関数という
-
関数名(引数1, 引数2, ...)
で関数を呼び出せる - 関数に
( )
で渡す値のことを引数という - 関数の計算結果のことを返り値または戻り値という
- 引数と返り値は型のルールが決まっており、間違えるとエラーになる
関数 | min(a, b) | max(a, b) |
---|---|---|
機能 | aとbの小さい方の値を返す(3つ以上も可能) | aとbの大きい方の値を返す(3つ以上も可能) |
関数 | sorted(list) | reversed(list) |
---|---|---|
機能 | リストをソートする(要素を小さい順に並び替える) | リストの要素の並びを逆にする |
組み込み関数
関数を使うとプログラムのまとまった機能を簡単に使うことができます。
関数の使い方
「2つの変数の値のうち小さい方を出力するプログラム」を例として見てみましょう。
関数を使わないで書く場合、次のようになります。
a = 10
b = 5
if a < b:
answer = a
else:
answer = b
print(answer)
5
「min関数」を使えば次のように書くことができます。
a = 10
b = 5
answer = min(a, b) # min関数
print(answer)
5
プログラム中に出てくる min
は2つの値のうち小さい方を求める関数です。
min(a, b)
の「計算結果」として a
と b
の小さい方の値が取得できるので、それを変数 answer
に代入しています。
標準ライブラリとは
Python には min
の他にも様々な関数が用意されており、多くの機能を自分でプログラムを書くこと無く利用できます。
Python で用意されている、関数等がまとまっているもののことを標準ライブラリ(Standard Library)といいます。また、標準ライブラリ内に用意されている関数のことを組み込み関数といいます。
関数を自分で作ることもできます。それについては「1.15.関数」で説明します。
関数の呼び出し方
関数を使うことを関数呼び出しといいます。
関数呼び出しの記法は以下の通りです。
関数名(引数1, 引数2, ...)
**引数(ひきすう)**とは、関数に渡す値のことです。 min(a, b)
では変数aと変数bがそれに当たります。
min関数では2つの引数がありましたが、引数の数は関数によって異なります。
関数の計算結果の値のことを**返り値(かえりち)または戻り値(もどりち)**といいます。
answer = min(a, b)
では、min関数の返り値を変数answerに代入しています。
引数と返り値の型
引数と返り値は関数によって型のルールが決まっており、間違うとエラーになります。
次のプログラムは、min関数の引数にint型とstring型を渡そうとして、エラーが発生しています。
s = "hello"
a = min(10, s)
print(a)
Traceback (most recent call last):
File "./Main.py", line 3, in <module>
a = min(10, s)
TypeError: unorderable types: str() < int()
関数の例
組み込み関数の中から2つの関数を紹介します。
これらを暗記しておく必要はありませんが、「この処理は組み込み関数でできた気がする」と思い出して調べられることが大切です。
min関数
min関数は、引数のうち一番小さい値を返します。3つ以上の引数にも対応しています。
answer = min(10, 5)
print(answer) # 5
5
引数と返り値の型
引数と返り値の型は、int
や float
のような数値型(または大小比較できる型)ならなんでも良いです。リストを引数に取ることもできます。
answer = min(1.5, 3.1)
print(answer) # 1.5
1.5
int型とfloat型の比較もできます。
a = 1.5
print("a:", type(a))
b = 10
print("b:", type(b))
answer = min(a, b)
print(answer) # 1.5
a: <class 'float'>
b: <class 'int'>
1.5
max関数
max関数は、引数のうち一番大きい値を返します。3つ以上の引数にも対応しています。
answer = max(10, 5)
print(answer) # 10
10
引数と返り値の型
引数と返り値の型についてはminと同様です。
リストを引数にする関数
組み込み関数の中から、リストを引数に渡す2つの関数を紹介します。
reversed関数
reversed関数を使うと、リストの要素の並びを逆にできます。
a = [1, 5, 3]
a = list(reversed(a)) # [3, 5, 1]
print(a)
[3, 5, 1]
イテレータが返ってくるため、list()
を使ってリストに変換しています。
また、スライスを使うことでも逆順のリストを取得することができます。
a = [1, 5, 3]
a = a[::-1]
print(a)
[3, 5, 1]
sorted関数
データ列を順番に並び替えることをソートといいます。
sorted関数を使うと、リストの要素を小さい順に並び替えることができます。
a = [2, 5, 2, 1]
a = sorted(a) # [1, 2, 2, 5]
print(a)
[1, 2, 2, 5]
また、sorted関数は第2引数に reverse=True
を指定すると、大きい順にソートできます。
a = [2, 5, 2, 1]
a = sorted(a, reverse=True) # [5, 2, 2, 1]
print(a)
[5, 2, 2, 1]
sum関数
sum関数は引数のリストの全要素の合計値を返します。
a = [2, 5, 2, 1]
print(sum(a))
10
問題
以下のリンク先に問題文が載っています。
EX14.三人兄弟の身長差
a, b, c = map(int, input().split())
# ここにプログラムを追記
解答例
必ず自分で問題に挑戦してみてから見てください。
解答例
1.15.関数
キーポイント
- 関数を作成することを関数を定義するという
def 関数名(引数1の名前, 引数2の名前, ...):
処理
- 関数の返り値はreturn文を使って
return 返り値
で指定する - 関数の返り値は書かないことも可能
- 関数の引数が不要な場合は定義と呼び出しで
()
だけを書く - 処理がreturn文の行に達した時点で関数の処理は終了する
- 引数に渡された値は基本的にコピーされる
関数
関数を作成することを関数を定義するといいます。
次の例では、組み込み関数のmin関数に近い機能を持つ関数 my_min
を定義しています。
# 関数定義
def my_min(x, y):
if x < y:
return x
else:
return y
answer = my_min(10, 5)
print(answer)
5
関数の動作
本家にプログラム全体の動作を説明したスライドがあります。
関数の定義
関数の定義は、関数呼び出しを行う行よりも前で行います。
関数定義の記法は次の通りです。
def 関数名(引数1の名前, 引数2の名前, ...):
処理
前の節で見た通り、引数は「関数に渡す値」、返り値は「関数の結果の値」のことです。
my_min関数は引数を2つ受け取るので、定義は次のようになります。
def my_min(x, y):
呼び出し方は組み込み関数と同様です。
次のように呼び出した場合、引数 x
に 10
が代入され、引数 y
に 5
が代入されます。
my_min(10, 5)
返り値の指定
関数の返り値は、return文で指定します。
return 返り値
my_min関数では2つの引数 x
, y
のうち小さい方を返すので、次のように書きます。
if x < y:
return x
else:
return y
返り値がない関数
関数の返り値が無いこともあります。その場合は、return文を書く必要はありません。
def hello(text):
print("Hello, " + text)
hello("Tom")
hello("Python")
Hello, Tom
Hello, Python
引数が無い関数
関数の引数が不要の場合は、定義と呼び出しでは ()
だけを書きます。
def int_input():
x = int(input())
return x
num = int_input()
print(num, type(num))
10
10 <class 'int'>
関数を自分で定義する理由
本家を参照してください。
注意点
return文の動作
処理がreturn文に到達した時点で関数の処理は終了します。
一つの関数の中にreturn文が複数あっても問題ありませんが、return文より後に書いた処理は実行されないことに注意しましょう。
次のプログラムでは、 "Hello, "
を出力した次の行で return
と書いているため、その後の処理は実行されません。
def hello():
print("Hello, ", end="")
return # この行までしか実行されない
print("world!")
return
hello()
Hello,
引数はコピーされる
他の変数に値を代入したとき同様に、基本的に引数に渡した値はコピーされます。
次のプログラムのadd5関数は関数内で引数に 5
を足していますが、呼び出し元の変数numの値は変化しません。
def add5(x):
x += 5
print(x)
num = 10
add5(num)
print(num)
15
10
関数が呼び出せる範囲
関数は宣言した行より後でしか呼び出せません。
次のプログラムでは、hello関数を定義した行より前でhello関数を呼び出しているため、エラーが発生しています。
hello()
def hello():
print("hello!")
Traceback (most recent call last):
File "./Main.py", line 1, in <module>
hello()
NameError: name 'hello' is not defined
上から順に読み込んで実行されるため、1行目の時点では「まだhello関数が定義されていません」とエラーが出ています。
問題
以下のリンク先に問題文が載っています。
EX15.三人兄弟へのプレゼント
# 1人のテストの点数を表すリストから合計点を計算して返す関数
# 引数 scores: scores[i]にi番目のテストの点数が入っている
# 返り値: 1人のテストの合計点
def sum_scores(scores):
# ここにプログラムを追記
# 3人の合計点からプレゼントの予算を計算して出力する関数
# 引数 sum_a: A君のテストの合計点
# 引数 sum_b: B君のテストの合計点
# 引数 sum_c: C君のテストの合計点
# 返り値: なし
def output(sum_a, sum_b, sum_c):
# ここにプログラムを追記
# ---------------------
# ここから先は変更しない
# ---------------------
# 1行の整数が空白区切りになった入力を受け取ってリストに入れて返す関数
# 引数 s: 1行の、整数が空白区切りになった入力
# 返り値: 受け取った入力のリスト
def list_int_input(s):
a = list(map(int, s.split()))
return a
# 科目数Nを受け取る
n = int(input())
# それぞれのテストの点数を受け取る
a = list_int_input(input())
b = list_int_input(input())
c = list_int_input(input())
# プレゼントの予算を出力
output(sum_scores(a), sum_scores(b), sum_scores(c))
解答例
必ず自分で問題に挑戦してみてから見てください。
解答例
おわりに
以上で第1章は修了です。
本記事では APG4b の第1章のみを扱いました。気が向いたら第2章以降も書こうと思います。
はじめに書いたように、問題があれば本記事は削除します。