Python | データ構造:list.pop

Python
スポンサーリンク

list.pop の概要(要素を取り出しつつ削除する)

list.pop は、リストから要素を取り出して同時に削除するメソッドです。戻り値として「取り出した要素」を返します。引数を省略すると末尾の要素、インデックスを渡すとその位置の要素が対象になります。元のリストが直接変更されるインプレース操作です。

fruits = ["apple", "banana", "orange"]
last = fruits.pop()
print(last)    # "orange"
print(fruits)  # ["apple", "banana"]
Python

基本動作と引数(ここが重要)

省略時は末尾、指定時はその位置

pop() はデフォルトで末尾を削除して返します。位置を指定したい場合は整数インデックスを渡します。

nums = [10, 20, 30, 40]
x = nums.pop()     # 末尾 40
y = nums.pop(1)    # インデックス1 → 20
print(x, y)        # 40 20
print(nums)        # [10, 30]
Python

負のインデックスも使える

末尾基準で位置を指定できます。-1 は末尾、-2 は末尾から2番目です。

letters = ["A", "B", "C", "D"]
print(letters.pop(-2))  # "C"
print(letters)          # ["A", "B", "D"]
Python

空リストに対してはエラー

対象要素がないため IndexError が発生します。事前に長さを確認するか、条件分岐で安全に扱います。

items = []
# items.pop()  # IndexError
if items:
    items.pop()
Python

remove・del との違い(重要ポイントを深掘り)

値で消すか、位置で消すか、返すか

  • remove(value): 最初に一致した「値」を削除。戻り値なし(None)。
  • pop(index=None): 「位置」の要素を削除して、その値を返す。
  • del リスト[index]: 「位置」の要素を削除。戻り値なし(文)。

「取り出した値を次の処理で使いたい」なら pop が最適です。「値指定で消したい」なら remove、「返り値不要の一括削除」やスライス削除は del が簡潔です。

items = ["a", "b", "c", "b"]

v = items.pop(1)   # 位置指定で削除して返す → "b"
# items.remove("b")  # 値指定で削除(先頭の"b")。返り値なし
# del items[0]       # 位置指定で削除。返り値なし
Python

実務での使いどころ(スタック・キュー・クレンジング)

スタック(後入れ先出し)の取り出し

末尾へ append、取り出しは pop。直感的で高速です。

stack = []
stack.append("task1")
stack.append("task2")
print(stack.pop())  # "task2"
print(stack)        # ["task1"]
Python

取り出した値を使った処理

「削除しつつ、その値で集計・判定」などが1行で書けます。

nums = [1, 5, 10]
total = 0
while nums:
    total += nums.pop()
print(total)  # 16
Python

キュー(先頭取り出し)は注意

先頭の pop(0) は全要素のシフトが発生して遅くなりがちです。頻繁な先頭取り出しは collections.deque を使うと効率的です。

from collections import deque
q = deque(["a", "b", "c"])
print(q.popleft())  # "a"(高速)
Python

重要ポイントの深掘り(性能と安全性)

計算量の違い

  • 末尾の pop(): 平均してほぼ O(1) で高速。
  • 中間や先頭の pop(i): 後ろの要素を前へ詰めるため O(n)。大量データで多用すると遅くなります。

用途に応じて「末尾中心」に設計する、先頭利用は deque に切り替えるなどの工夫が有効です。

戻り値の活用と誤用防止

pop は「削除した値」を返します。None ではないため、即座に使えます。一方、remove や del は戻り値がないので、値が必要なら pop を選びます。削除後のリスト状態を前提とする処理は、pop の直後に書くと意図が明確です。

エラー対策(空と範囲)

空リストや範囲外インデックスは IndexError になります。防ぐには「条件で存在チェック」「try/except で補足」「業務ロジック上の不変条件(空にしない)」のいずれかで設計します。

try:
    value = items.pop(5)
except IndexError:
    value = None
Python

例題で身につける(定番から一歩先まで)

例題1:ログの最新を取り出して処理

logs = ["start", "load", "run", "finish"]
last = logs.pop()
print(last)  # "finish"
print(logs)  # ["start", "load", "run"]
Python

例題2:先頭を取り出すが、回数が少ない場合

names = ["A", "B", "C"]
first = names.pop(0)  # 先頭取り出し(少量なら許容)
print(first, names)   # "A" ["B", "C"]
Python

例題3:値を取り出しつつ合計・最大を更新

nums = [7, 3, 12, 5]
total = 0
max_v = float("-inf")
while nums:
    v = nums.pop()
    total += v
    if v > max_v:
        max_v = v
print(total, max_v)  # 27 12
Python

例題4:取り出した値で分岐(在庫処理)

stocks = [("coffee", 2), ("tea", 1)]
item, qty = stocks.pop()
print(item, qty)  # "tea" 1
# 取り出した在庫を出荷処理へ渡す…など
Python

まとめ

list.pop は「位置で削除して、その値を返す」インプレース操作で、末尾なら高速、先頭や中間は O(n) のコストがかかります。値を使いながら削除する場面(スタック、集計、分岐)に強く、remove(値指定・戻り値なし)や del(文・戻り値なし)と明確に使い分けるのがポイントです。空リストや範囲外では IndexError になるため、事前チェックや例外処理で安全に。頻繁な先頭取り出しは deque へ切り替える設計にすると、規模が大きくなっても安定して動きます。

タイトルとURLをコピーしました