月影

日々の雑感

Pythonデータ構造10選 | 計算量とメモリ効率をE資格レベルで徹底解説 その1

 

E資格レベル:Pythonデータ構造 10本ノック

リスト・タプル・辞書・集合のメモリ管理と計算量
基礎 / エラー処理

Q1. 辞書のキーとしての制約

以下のコードを実行した際の結果として正しいものはどれか。

my_dict = {}
key_a = (1, 2)
key_b = [1, 2]

my_dict[key_a] = "Tuple"
my_dict[key_b] = "List"
答えを見る

正解:C. key_b の代入で TypeError が発生する

解説:辞書のキーは「ハッシュ可能(Hashable)」である必要があります。
タプルはイミュータブル(不変)なのでハッシュ可能ですが、リストはミュータブル(可変)なのでハッシュ値を持てず、キーにできません。エラー内容は TypeError: unhashable type: 'list' です。

計算量 (Big-O)

Q2. 所属確認(in演算子)の速度

素数N = 1,000,000 のデータ構造に対して、ある値が含まれているかを確認する x in data 操作を行う。
平均計算量が O(1) となるデータ構造の組み合わせとして正しいものはどれか。

答えを見る

正解:C. 集合(Set) と 辞書(Dictionary)

解説:
SetとDict: ハッシュテーブルで実装されているため、検索の平均計算量は O(1) です。
ListとTuple: 線形探索を行うため、計算量は O(N) となります。大規模データでの検索速度には劇的な差が出ます。

メソッドの挙動

Q3. append と extend の違い

以下のコードを実行した後の a の中身として正しいものはどれか。

a = [1, 2]
b = [3, 4]
a.append(b)
答えを見る

正解:B. [1, 2, [3, 4]]

解説:
append は引数を「1つの要素」としてそのまま追加します。
リストを連結して [1, 2, 3, 4] にしたい場合は、extend() メソッドまたは + 演算子を使用する必要があります。

データ構造の特性

Q4. 集合へのアクセス

集合(Set)オブジェクト s = {10, 20, 30} に対して実行すると エラー になる操作はどれか。

答えを見る

正解:C. val = s[0]

解説:
集合(Set)は順序を持たない(Unordered)データ構造です。そのため、インデックス(添字)によるアクセスはサポートされておらず、TypeError が発生します。要素を取り出すにはループで回すか、pop() を使います。

メモリ管理

Q5. リストの浅いコピー(Shallow Copy

以下のコードの出力結果はどれか。

list_a = [[1, 2], [3, 4]]
list_b = list_a.copy()

list_b[0][0] = 9
print(list_a[0][0])
答えを見る

正解:B. 9 (変更される)

解説:
copy() は「浅いコピー」を作成します。外側のリストは別のオブジェクトになりますが、中の要素(この場合は内側のリスト [1, 2])への参照(アドレス)は共有されたままです。
完全に独立させるには copy.deepcopy() が必要です。

例外処理回避

Q6. 辞書の get メソッド

辞書 d = {'a': 1} に対し、キーが存在しない場合でもエラーを出さずに 0 を取得したい。正しいコードはどれか。

答えを見る

正解:B. d.get('b', 0)

解説:
d.get(key, default) メソッドは、キーが存在すればその値を、存在しなければ第二引数(デフォルト値)を返します。最もPythonicで推奨される書き方です。
Dも動作はしますが、Bの方が簡潔で効率的です。

構文

Q7. アスタリスク(*)を使ったアンパッキング

以下のコードを実行した際、mid 変数に入る値はどれか。

data = (1, 2, 3, 4, 5)
head, *mid, tail = data
答えを見る

正解:C. [2, 3, 4] (リスト)

解説:
Pythonアスタリスク付きアンパッキングでは、残りの要素が常にリストとして代入されます。元のデータがタプルであっても、受け皿(mid)はリストになります。

Q8. 積集合(共通部分)の取得

2つの集合 A = {1, 2, 3}B = {3, 4, 5} の共通する要素 {3} を取得する演算子はどれか。

答えを見る

正解:D. A & B

解説:
& (AND): 積集合 (共通部分)
| (OR): 和集合 (すべて)
- (SUB): 差集合 (AにあってBにないもの)
^ (XOR): 排他的論理和 (どちらか片方だけにあるもの)

メモリ効率

Q9. タプル内包表記...ではない?

以下のコードを実行した際、x の型(Type)は何になるか。

x = (i for i in range(10))
答えを見る

正解:C. generator

解説:
丸括弧 () で囲んだ内包表記は、タプルではなくジェネレータ式(Generator Expression)を作成します。タプルを作りたい場合は tuple(i for i in range(10)) と明示的にキャストする必要があります。

言語仕様の変更

Q10. 辞書の順序保持

Python 3.7以降の仕様において、以下の辞書を for k in d: でループさせた時の順番について正しい記述はどれか。

d = {}
d['b'] = 2
d['a'] = 1
d['c'] = 3
答えを見る

正解:C. 要素を追加した順 (b, a, c) が保証される

解説:
Python 3.6以前では辞書の順序は不定でしたが、Python 3.7以降は「挿入順序を保持すること」が言語仕様として保証されています。