【要約】現役シリコンバレーエンジニアが教える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'