【要約】現役シリコンバレーエンジニアが教えるPython3 データ構造
# スライスの基本 # a[始まりの位置: 終わりの位置: スライスの増分] list = [1, 2, 3] # 要素を一つ飛ばしで参照する。 print(list[::2]) # 要素をひっくり返す。 print(list[::-1])
ネストした配列も作れる。
文字列の配列と数字の配列が共存できるのは動的言語っぽい。
個人的に間違えそうだなと思ったもの。
# e[1] ~ e[2]に代入する。 e = [1,2,3,4] e[1:2] = ["a", "b"] print(e) [1, 'a', 'b', 3, 4] # e[1] ~ e[3]に代入する。ただし、e[3]に代入するものはない e = [1,2,3,4] e[1:3] = ["a", "b"] print(e) [1, 'a', 'b', 4]
上書きする要素が少ないとリストの長さが短くなるみたい。これはpython側でエラーを出して欲しいところ。
# 後ろに数字を付け加える。 e = [1,2,3,4] e.append(100) print(e) # 位置指定で挿入 e.insert(0, 1000) print(e) # 最後の要素を取り出す(リストから要素が消える。) print(e.pop()) # 位置指定で要素を取り出す(リストから要素が消える。) print(e.pop(0)) # 特定の要素を指定して一番先頭のもの削除する # なかったらエラーが返ってくる。 # いちいちindexを調べて削除しなくて済むのはありがたい。 e.remove(2) print(e) [1, 2, 3, 4, 100] [1000, 1, 2, 3, 4, 100] 100 [1000, 1, 2, 3, 4] [1, 3, 4]
del
というのは対処を削除したり、未定義にする。
他の言語でこんな機能あったって?と思って印象的だった。
もちろん未定義の変数を呼び出すとエラーになる。
e = [1,2,3,4] del e[0] print(e) del e print(e) [2, 3, 4] NameError: name 'e' is not defined
リストのメソッド
e = [1, 2, 3, 100, 5, 6] # 逆向きソート(普通のソートはreverseを外す) e.sort(reverse=True) print(e) # 逆向きソート(上と同じだが、結果的にsort同じ結果になる。) e.reverse() print(e) [100, 6, 5, 3, 2, 1] [1, 2, 3, 5, 6, 100]
僕はreverse
派かな〜
文字列<=>配列
# 文字列を配列にする。 # 空文字ごとにリストに入れる。 s = 'I am God' s_split = s.split(' ') print(s_split) # 配列から文字列に戻す。 # 区切り文字を@@@@@@@@にして文字列にする。 l = '@@@@@@@@'.join(s_split) print(l)
リストのコピー
# リストのコピー(参照渡し) i = [1, 2, 3] j = i j[0] = "a" print(i) print(j) # リストのコピー(値渡し) x = [1, 2, 3] y = x.copy() y[0] = 100 print(x) print(y)
なるべくcopy()
を使っていきたい。後述する辞書型でも同じように参照渡しするので、copyを使っていきたい。
ちなみにid()
というメソッドを使うと参照渡し、値渡しかどうか判別できる。参照渡しだと同じIDを示す。
ここからは対話型で実行していく(print書くのが手間なので)
タプル型について
タプルは変更できない配列?だと思っている。
ただし、タプルにネストされた配列の要素をは変更できる。
使いみちとして、今後変更したくないリストの代わりに使い、コーディングミスを減らすことができる。
# 2種類の宣言 # かっこ式 >>> e = (1, 2, 3) >>> e (1, 2, 3) # カンマ式 >>> a = 1 , 2, 3 >>> a (1, 2, 3) >>> t = (1,) >>> t (1,) # カンマ式がバグを生みそう >>> s = 1, >>> s (1,) # ただ要素が一つだけのタプルを作ることができる。(多分使わない。) # タプルの結合 # タプルの値を編集できないが、新しいタプルを作って結合することができる >>> x = (1, 2, 3) + (4, 5, 6) >>> x (1, 2, 3, 4, 5, 6)
タプルのアンパッキング
タプルの要素をそのまま変数に格納できる。他の言語であんまり見たことないと思った。
# 普通のアンパッキング >>> v = 1, 2 >>> v (1, 2) >>> i, j = v >>> i 1 >>> j 2 # ただ、xとyの値を交換してるだけだと思うが、 x, y = y, xの部分でアンパッキングを使って値を交換してる。 # 一行で複数の変数に代入する記述と混同しそう。 >>> x, y = 1, 9 >>> x, y = y, x >>> x , y (9, 1) >>> x 9 >>> y 1
辞書型
ハッシュテーブルを用いているのでリストよりもkeyで検索するのが速い。
# 宣言 # 一番採用したい書き方 >>> d = {"a": 1, "b" : 2} >>> d {'a': 1, 'b': 2} >>> dict(a=1,b=2) {'a': 1, 'b': 2} # この書き方はしたくない >>> dict([("a", 100), ("b", 200)]) {'a': 100, 'b': 200} # 辞書型への追加 >>> d["c"] = 3 >>> d {'a': 1, 'b': 2, 'c': 3}
辞書型のメソッド
特に覚えて置きたいのが、辞書型で存在しないkeyを指定した際の処理。
辞書型で値を参照するときはgetメソッドを使ったほうがいいかも。
>>> d = {"a" : 1, "b" : 2} # メソッドを使うとエラーは出ずなにも返さない。 >>> d.get("c") # この場合はエラーが出る。 >>> d["c"] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'c'
集合
型set
となる。
定義では辞書型と同じ波括弧を使うので間違えて書きそう。
PHPに集合の機能ってこんなあったっけ?w
>>> a = {1, 2, 3, 4, 4, 4, 5 , 5, 6} # 重複がなくなる。 >>> a {1, 2, 3, 4, 5, 6} >>> b = {4, 5, 6} >>> b {4, 5, 6} # お互いの重複する部分 >>> a & b {4, 5, 6} # 値の全種類 >>> a | b {1, 2, 3, 4, 5, 6} # 片方だけが持っている値 >>> a ^ b {1, 2, 3} # お互いの重複しない部分を取得 # aにとって重複しない部分 >>> a - b {1, 2, 3} # bにとって重複しない部分 # set()は空の集合 >>> b - a set() # お互いを足すとエラーがでる。 >>> a + b Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: 'set' and 'set'