0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

pythonエンジニア認定試験受験記②

Last updated at Posted at 2021-06-13

本記事について

以下のオデッセイ開催のpython基礎認定試験を今度受験するにあたり
勉強して上で学んだことを記事でアウトプットしていく。
前回記載の記事が長くなっていたのでパート2で分けていく

map関数とは

知らない!
そんな関数あったことすら知らなかったがpythonチュートリアルに

squares = list(map(lambda x: x**2, range(10)))

そしてこれと等価なのが

squares = [x ** 2 for x in range(10)]

とか書いてある。
後者はrangeで0~9までループ回して結果を冪乗するというプログラムなのだろう
でも前者の説明が全くないのである。流石オライリー!
なのでmap関数をまぬあるで調べてみる

map(function, iterable, ...)
function を、結果を返しながら iterable の全ての要素に適用するイテレータを返します。追加の iterable 引数が渡されたなら、 function はその数だけの引数を取らなければならず、全てのイテラブルから並行して取られた要素に適用されます。複数のイテラブルが与えられたら、このイテレータはその中の最短のイテラブルが尽きた時点で止まります。関数の入力がすでに引数タプルに配置されている場合は、 itertools.starmap() を参照してください。

ということでmap関数は
map(function, iterable, ...)
なので先の
squares = list(map(lambda x: x**2, range(10)))
についてはrange(10)のイテラブルを引数としてlambda x: x**2を実行するとなる。
よって

map(lambda x: x**2, range(10))

についてはrangeで0~9まで抜き出した値がlambdaに都度代入される
その上でその結果をlist()に渡しているので結果としてはx**2をリストに入れている

list([0, 1, 4, 9, 16, 25, 36, 49, 64, 81])

故に実行結果としては以下のように0~9の冪乗のリストが出来上がる

実行結果
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

リスト内包にフィルターをかける方法

[(x, y) for x in [1, 2, 3 ] for y in [3, 1, 4] if x != y]

パッと何をやっているのか分かりにくいが、一番大事なのは
if x != y
の部分であるつまりxとyがnotイコールだったら最初のタプルに値を入れて良い
というコードである。つまり出力結果にフィルターをかけているのである。
あとはforの二重ループなので、以下のような動きとなる

x=1, y=3 x != yなのでリストにappend -> (1, 3)
x=1 ,y=1 x == yなのでリストにappendされない
x=1 ,y=4 x != yなのでリストにappend -> (1, 4)

x=2, y=3 x != yなのでリストにappend -> (2, 3)
x=2 ,y=1 x != yなのでリストにappend -> (2, 1)
x=2 ,y=4 x != yなのでリストにappend -> (2, 4)

x=3, y=3 x == yなのでリストにappendされない
x=3 ,y=1 x != yなのでリストにappend -> (3, 1)
x=3 ,y=4 x != yなのでリストにappend -> (3, 4)

出力結果
[(1, 3)(1, 4)(2, 3)(2, 1)(2, 4)(3, 1)(3, 4)]

同じような感じでリストから50以上の値を抜いてリストを作りたいという時には以下のようにやってやれば良い。とっても簡単である

l = [3, 20, 50 ,15, 25, -3, 100 , 65]
print([i for i in l if i >= 50])
出力結果
[50, 100, 65]

zip関数

複数リストの結合をしたいときに使うのがzip関数
具体的には以下のような形

data = [
    ['Yamada', 'Tanaka', 'Kojima'],
    [25, 34, 29],
    ['Tokyo', 'Ibaragi', Kagoshima]
]
profile = [i for i in zip(*data)]
print(profile)
出力結果
[('Yamada', 25, 'Tokyo'), ('Tanaka', 34, 'Ibaragi'), ('Kojima', 29, 'Kanagawa')]

ポイントは*dataで二重リストをアンパッキングしてzip関数に渡しているところである
※ただしお互いのリストの数が同じでないと出力されないので注意

タプルのアンパッキング

例えば以下のように最後にカンマをつけるとタプルになる
タプルはイミュータブルなので変更はできないがミュータブルな要素をタプルに入れることはできる

a = 'Hello',
print(a)
実行結果
('Hello',)

ミュータブルなので勿論range関数とかも入れられる

a = range(3),
print(a)
実行結果
(range(0, 3),)

これをそのまま複数の変数に入れられたりする

b, c ,d = a[0]
print(b, c, d)
実行結果
0 1 2

これを シーケンスアンパッキング!!! と呼ぶ
※実に厨二心をくすぐるかっこいい言葉だと思う。必殺技として叫びつつ黒歴史ノートに是非とも記載してほしい。

###集合

重複除去で主に使うと思うのが集合である
複数ある場合は{}の中に重複除去したいものを入れる
重複除去した結果はsorted等でソートしてリストで返してやるのが良いと思う

print(sorted({'Apple', 'aPplE', 'apple', 'Apple'}))
実行結果
['Apple', 'aPplE', 'apple']

一つだけの場合はset()を使うと良い

print(sorted(set('abcabcabc')))
実行結果
['a', 'b', 'c']

###辞書内包表記

辞書内包表記は大体タプルの時と一緒なので以下のようにリストから辞書にコンバートできる

sample_list = ['Apple', 'Orange', 'banana']
fruits_dict = {k: v for k ,v in enumerate(sample_list)}
print(fruits_dict)
実行結果
{0: 'Apple', 1: 'Orange', 2: 'banana'}

アルファベットのa-zまでに0からの数字を入れた辞書を作りたいなんて場合は次のようにしてやれば良い。※a-zまで書くのが面倒なのでこういう時はstringモジュールを使うとすごい楽ができる

import string
alphabet = {v: i for i, v in enumerate(string.ascii_uppercase[:26])}
print(alphabet)
出力結果
{'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7, 'I': 8, 'J': 9, 'K': 10, 'L': 11, 'M': 12, 'N': 13, 'O': 14, 'P': 15, 'Q': 16, 'R': 17, 'S': 18, 'T': 19, 'U': 20, 'V': 21, 'W': 22, 'X': 23, 'Y': 24, 'Z': 25}

###シーケンスの比較

以下の判定がどのように行われるかをチェックする

問題
(1, 2, 3) < (1, 2, 4)
[1, 2, 3] < [1, 2, 4]
'ABC' < 'C' < 'Pascal' < 'Python'
(1, 2, 3, 4) <(1, 2, 4)
(1, 2) < (1, 2, -1)
(1, 2, 3) < (1.0, 2.0, 3.0)
(1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4)

実際はこのような形で判定が行われる

問題
(1, 2, 3) < (1, 2, 4)
[1, 2, 3 < [1, 2, 4]
実行結果
True
True
リストもタプルも結果は一緒
判定内容
※リストもタプルも判定内容は一緒
1 < 1 False
2 < 2 False
3 < 4 True
問題
'ABC' < 'C' < 'Pascal' < 'Python'
実行結果
True
判定内容
A < C True

Cはアルファベット順で判定される
厳密にはアルファベットのユニコード値で判定される
ord('A') #65
ord('C') #67
なので A < C はCが大きいとなる

- 20210614追記
アルファベットは大文字より小文字のが大きいと判断される

例えば

'H' < 'E'  False
だが
'H' < 'e'  True
となる
問題
(1, 2, 3, 4) <(1, 2, 4)
実行結果
True
1 < 1 False
2 < 2 False
3 < 4 True
問題
(1, 2) < (1, 2, -1)
実行結果
True
1 < 1 False
2 < 2 False
残りの要素数が多い方が大となるので-1がある右側のtupleが大
よって結果としてはTrue
問題
(1, 2, 3) < (1.0, 2.0, 3.0)
実行結果
False
判定内容
1 < 1.0 False
2 < 2.0 False
3 < 3.0 False
問題
(1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4)
実行結果
True
判定内容
1 < 1 False
2 < 2 False

('aa', 'ab') < ('abc', 'a')
の比較なので
'aa' < 'abc'をまず考える

a < a False
a < b True

###文字列出力関数str, repr, eval, printの違い

from datetime import date

a = type(date.today()), date.today()
b = type(print(date.today())), print(date.today())
c = type(repr(date.today())), repr(date.today())
d = type(eval("date.today()")), eval("date.today()")
e = type(str(date.today())),str(date.today()) 
print('date: ', a, '\nprint: ', b,'\nrepr: ', c,'\neval: ', d,'\nstr: ', e)
実行結果
date:  (<class 'datetime.date'>, datetime.date(2021, 6, 14))
print:  (<class 'NoneType'>, None)
repr:  (<class 'str'>, 'datetime.date(2021, 6, 14)')
eval:  (<class 'datetime.date'>, datetime.date(2021, 6, 14))
str:  (<class 'str'>, '2021-06-14')

なんとなくお分かり頂けただろうか?
1番上はdate関数をtodayで出力した場合、単純にdatetime.date型で出力されている
2番目はprintでその出力結果を出した場合、print文は基本Noneを戻り値として返すことがわかる
3番目がrepr関数でdate関数をtodayで出力した場合、reprは文字列strとして返すがstrとの違いとして実行結果をそのまま返すのか、実行結果前の式の状態で返すのかの違いがある模様
こちらは5番目の出力のstrを見るとわかる
5番目のstrでdate関数をtodayで出力した場合、出力結果として加工した後の'2021-06-14'という日付を返してくれるのでそのまま他の処理で使えるがreprの場合は関数を実行したけ結果を'datetime.date(2021, 6, 14)'のような型として返してくるのでそのままでは使えない
使うためにはprintとかstrで別途実行してやる必要がある

次のような形である

print(datetime.date(2021, 6, 14))
str(datetime.date(2021, 6, 14))

という形でなんとなく違いはわかっていただけたかと思う

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?