A.1.2 文字列
フォーマット文字列
文字列の中に変数を表示させたいときがある。そのような場合には、以下のフォーマット文字列を用いる。
x = 100
y = 3.14
print(f"{x} と {y}")
問題
文字列 s='PythonVideoCheckProblem' から,スライス表記を用いて 'onVide' を抜き出しなさい.
文字列s='PythonVideoCheckProblem' をすべて大文字にしなさい.
以下の文字列,並びに format を用いて,'Python,Video,Check,Problem' を作成しなさい.なお,単語の間には ',' を挟むこと.
s1 = 'Problem' s2 = 'Python' s3 = 'Check' s4 = 'Video'
引数として与えた文字列が全て小文字なら True.そうでないなら Falseを返す関数を作りなさい. 例として,文字列 s='PyThOn' を関数の引数として与えて判定しなさい.
小文字として与えた文字列の先頭が母音('a','i','u','e','o')である場合には,'an 'を,そうでない場合には 'a 'を加えた文字列を返す関数を作れ. 例として,'apple'と'pen'を引数として与えた関数の返値を出力せよ.
A.1.3 リスト
主なメソッド
- L.count(x) : L内での xの生起回数を返す.
- L.index(x) : L内で xが最初に発生する添え字を返す.ない場合には例外(エラー名)を返す.
- L.append(x) : Lの最後に要素 xを追加する. L+=[x] と同じ効果.
- L.insert(i,x) : Lの $i$番目の添え字に要素 x を挿入する. L[i:i] =[x] と同じ効果.
- L.remove(x) : Lで最初に発生する x を削除する.
- L.extend(L2) : Lの末尾にリスト L2を追加する.
- L.pop(i) : Lの i番目の要素を削除し,返す.iが省略された場合には最後の要素を削除.
- L.reverse() : Lを逆順にする.
- L.sort() : Lを小さい順に並べ替える.
- enumerate(L) : リスト Lの添え字と要素のタプルのジェネレータを返す.
問題
リスト L = [ 'Marvelous', 'Fantastic', 'Amazing!!' ] 内の文字列を,s='Python!! ' を区切り文字として結合し,表示せよ
文字列s = 'Payatahaoan' のうち,'a' を区切り文字として文字列s を分割したリストで表示せよ.
リスト L = [1,2,3,4,5] が与えられている.
(1). 2番目の要素を削除せよ.
(2). L の2番目に 300 を代入せよ.
(3). L を逆順にせよ.
(4). スライス表記を用いて,2番目に [10,20] を代入せよ.
(5). メソッド append を用いて 100 を追加せよ.
問題
文字列 s='May I have a large container of coffee'を空白を区切り文字として分割し,分割した文字列の長さを順に表示せよ.何になるか?
文字列 s='How I want a drink alcoholic of course after the heavy lectures involving quantum mechanics and if the lectures were boring or tiring then any odd thinking was on quartic equations again' を空白を区切り文字として分割し,分割した文字列の長さを順に表示せよ.何になるか?
A.1.6 集合
主なメソッド
- S.add(x) : 集合Sに要素xを加える.
- S.pop() : 集合Sから適当な要素を抽出し,その要素を削除する.
- S.remove(x) : 集合Sから要素xを削除する.
- S.issubset(T) : 集合Sが集合Tの部分集合であるときTrue,そうでないときFalseを返す. $S<=T$ と同じ効果.
- S.issuperset(T) : 集合Tが集合Sの部分集合であるときTrue,そうでないときFalseを返す. $S>=T$ と同じ効果.
- S.union(T) : 集合SとTの和集合を返す. $S|T$ と同じ効果.
- S.intersection(T) : 集合SとTの共通部分を返す. $S \& T$ と同じ効果.
- S.difference(T) : 集合SとTの差集合を返す. $S-T$ と同じ効果.
- S.symmetric_difference(T) : 集合 SとTの対称差集合(S と T のうち,共通部分に含まれない要素から成る集合)を返す. $S$^$T$ と同じ効果.
A.2 演算子
演算子は他のプログラミング言語と同様に,以下の順で優先順序をもつ.
- 括弧 ( )
- べき乗(指数演算) $**$
- 乗算 $*$ ,除算 $/$, 整数除算 $//$, 剰余 %
- 加算 $+$, 減算 $-$
Python3では,割る数と割られる数が両方とも整数の場合でも,除算 $/$ は浮動小数点数を返す. たとえば, $4/5$ は0.8を返す. 整数除算を行いたい場合には,演算子 $//$ を用いる.たとえば, $4//5$ は0を返し, $4//5.0$ は0.0を返す.
文字列やリストに対しても数値と同様の加算や乗算を行うことができる. たとえば,文字列 s='abc'に対して, s+'d' は'abcd'を返し, $s*2$ は'abcabc'を返す. リストでも同様に$[0]*3$ は[0, 0, 0]を返す.
if文やwhile文の中では,比較や論理条件を表す演算子が用いられる. <= は以下,< は未満,>= は以上,> は大きい,==は等しい,!= は等しくないときに真になり, それ以外のとき偽になる演算子である.
isは2つのオブジェクトが等しいか否かを判定する演算子である. たとえば,L=[1,2]に対して,L==[1,2]は真であるが,L is [1,2]は偽となる.
in は集合やリストなどの要素であるとき,not in は要素でないときに真になり,それ以外のとき偽になる演算子である. たとえば, リストL=[5,6,3,2]に対して3 in Lは真を返す.
in 演算子は日本語の文字列 'あけまして' に対しても適用可能であり 'あ' in Lは真を返す. 論理演算子and やor は,それぞれ論理積と論理和をとる演算子である. 真を正の整数(通常は $1$),偽を $0$ としたとき,論理積は乗算,論理和は加算に対応する. たとえば,(1<4) or (5<4)は1<4が真なので,$1+0=1$ となるので,真になる.
他にも, 展開演算子($*$と$**$)がある.
演算子 $*$ をリスト,集合,辞書などの前に付けることによって,その要素(辞書の場合にはキー)をタプルに展開する.
例として,集合,辞書,ジェネレータ(リスト)をそのまま出力する場合と,タプルに展開してから出力する場合を以下に示す.
a = {1, 2, 3, 4}
b = {"hello": "world"}
c = range(5, 10)
print(a, b, c)
print(*a, *b, *c)
演算子 $*$ は,以下のように2つのリスト内から,最小の要素を探すときに便利である.
L1 = [6, 3, 4, 300, -10]
L2 = [5, 8, 4, 3, 100]
print(min(*L1, *L2))
演算子 $*$ がタプルに展開するのに対して,演算子 $**$ は辞書に展開する.
例として,3つの辞書を展開してから再び1つの辞書としてまとめてみる.
d1 = {"Sara": 165, "Mickey": 120}
d2 = {"Minny": 110}
d3 = {"Kitty": "Three Apples", "Mickey": 200}
{**d1, **d2, **d3}
キー'Mickey'の値が200になっていることから分かるように,キーが同じ場合には,後に書いた辞書(この場合にはd3)の値に上書きされる.
展開演算子は,関数の複数の引数の指定の際に用いられる.
位置引数とキーワード引数
関数の引数は順番で指定する位置引数と、名前を指定するキーワード引数がある。
位置引数の後にキーワード引数を書く.
def f(name, weight):
print("Name is", name, "whose Weight is", weight, "kg")
f("Kitty", 2) # 位置で呼び出し
f(name="Kitty", weight=2) # キーワードで呼び出し
f("Kitty", weight=2) # 位置とキーワードを混ぜて呼び出し(位置引数は必ずキーワード引数の前;逆にするとエラーする)
>>> いずれも以下の出力を得る。
Name is Kitty whose Weight is 2 kg
任意の数の引数
数が事前には分からない複数の引数も定義できる。位置引数の場合には*args
(argumentsの略)で、キーワード引数の場合には**kwards
(keywordsの略)で指定する。
例えば、引数の和を返す関数を位置引数を用いて書くと、以下のようになる。
def f(*args):
s = 0
for i in args:
s += i
return s
f(1, 2, 3, 4, 5)
> >>
15
名前と任意の数の属性を出力する関数は、キーワード引数を用いて、以下のように書くことができる。
def f(name, **kwards):print(f"Name is {name}") for i in kwards:
print(i, " is ", str(kwards[i]))
f("Kitty", weight=2, height=80)
>>>
Name is Kitty
weight is 2
height is 80
A.8 モジュール
import モジュール名
import モジュール名 as 別名
from モジュール名 import 関数やクラス
randomモジュールの主要な関数
- seed(x) : xを用いて乱数の初期化を行う. xを省略した場合には現在のシステム時間で初期化される.
- random() : $[0.0, 1.0)$ の一様ランダムな浮動小数点型の数を返す.
- randint(i,j) : 整数 $i,j$ ($i$ $\leq$ $j$) に対して $i \leq k \leq j$ の一様ランダムな整数 $k$ を返す.
- shuffle(L) : リストLの順序をランダムに混ぜる.
- choice(L) : リストLからランダムに1つの要素を選択する.
問題
mathモジュールをインポートし,
$2$ の平方根を表示せよ.
$6$ の階乗を表示せよ.(階乗を表示するには,factorial() を用いる.)
random モジュールから,randint関数, shuffle関数 のみをインポートし、
$-5$ 以上,$3$ 以下の一様ランダムな整数を発生させよ.
リスト $L = [1,2,3,4]$ の順序をランダムに混ぜよ.
itertoolsモジュールをインポートし,
- range(5)内の要素の長さ $2$ の(繰り返しを許さない)順列を生成し,リスト型で表示せよ.
- range(5)内の要素の長さ $2$ の(繰り返しを許さない)組み合わせを順に生成し,リスト型で表示せよ.
問題(randomモジュールの応用)
- 各期の需要が平均100,標準偏差10の正規分布のとき,100期分のシミュレーションを行い,需要が110を超える期数を調べるプログラムを作成せよ.
(ヒント:正規分布にしたがう擬似乱数はrandomモジュールのgauss関数(もしくはnormalvariate関数)で生成できる.引数は平均と標準偏差である. )
- あるスーパーで販売しているある商品の在庫を管理したい.
いま,$t-1$日の在庫量の営業後に在庫を調べて,発注量 $x[t]$ を決める.発注した商品は翌日の朝に届き, それによって $t$ 日の営業後の在庫 $I[t]$ は,以下のように決まるものとする.
$$ I[t] = I[t-1]+x[t] –D[t] $$ここで $D[t]$ は$t$日の需要量であり,需要が平均100,標準偏差10の切断正規分布(負の場合には0とした正規分布)とする. また,最初の日($t=0$)の営業後の在庫は0であると仮定する.
以下の2つの在庫管理方策のプログラムを作成せよ.
(s,S)方策:在庫量 $I[t-1]$ が $s$ 未満であるなら,翌朝の在庫が $S$ になるように発注する.
(Q,R)方策:在庫量 $I[t-1]$ が $R$ 未満であるなら,$Q$ だけ発注する.
100日のシミュレーションの後で,発注費用,在庫費用,品切れ費用の合計を計算するプログラムを作成せよ.ただし,毎日の営業後の在庫量が0以上の場合には1個あたり10円の在庫費用がかかり,在庫量が負の場合には,1個あたり100円の品切れ費用がかかるものとする.(負の在庫は顧客が待っている状態を表し,翌日の朝に商品を引き取ると仮定する.これをバックオーダーと呼ぶ.)また,発注を行う度に(発注量が正のときに)発注費用1000円がかかるものとする.また,作成したプログラムを用いて,各方策のパラメータはどのように設定すれば総費用が最小になるか考察せよ.