Pythonスライス記法完全マスターガイド – 基本から応用テクニックまで徹底解説
Pythonのスライス記法は、リスト、文字列、タプルなどのシーケンス型データから部分的にデータを取得する強力な機能です。基本的な使い方から高度な応用テクニックまで、スライス記法をマスターすることで、より効率的で読みやすいPythonコードを書くことができます。この記事では、スライス記法のあらゆる使い方を実例とともに詳しく解説します。
1. スライス記法の基本構文
スライス記法の基本的な構文は以下の通りです:
sequence[start:stop:step]
最も基本的な例:
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(numbers[2:7]) # [2, 3, 4, 5, 6]
print(numbers[:5]) # [0, 1, 2, 3, 4]
print(numbers[5:]) # [5, 6, 7, 8, 9]
2. 基本的なスライス操作
開始位置と終了位置の指定
fruits = ["apple", "banana", "orange", "grape", "melon"]
print(fruits[1:4]) # ['banana', 'orange', 'grape']
print(fruits[0:3]) # ['apple', 'banana', 'orange']
開始位置または終了位置の省略
data = [10, 20, 30, 40, 50]
print(data[:3]) # [10, 20, 30](最初から3番目まで)
print(data[2:]) # [30, 40, 50](2番目から最後まで)
print(data[:]) # [10, 20, 30, 40, 50](全体のコピー)
3. ステップ(step)の活用
基本的なステップ指定
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(numbers[::2]) # [0, 2, 4, 6, 8](2つおき)
print(numbers[1::2]) # [1, 3, 5, 7, 9](1番目から2つおき)
print(numbers[::3]) # [0, 3, 6, 9](3つおき)
逆順の取得
text = "Python"
print(text[::-1]) # "nohtyP"(文字列を逆順に)
numbers = [1, 2, 3, 4, 5]
print(numbers[::-1]) # [5, 4, 3, 2, 1](リストを逆順に)
4. 負のインデックスを使ったスライス
data = [10, 20, 30, 40, 50, 60, 70]
print(data[-3:]) # [50, 60, 70](後ろから3つ)
print(data[:-2]) # [10, 20, 30, 40, 50](後ろから2つを除く)
print(data[-5:-2]) # [30, 40, 50](後ろから5番目〜2番目)
5. 文字列でのスライス
基本的な文字列スライス
message = "Hello World"
print(message[0:5]) # "Hello"
print(message[6:]) # "World"
print(message[:5]) # "Hello"
print(message[::2]) # "HloWrd"(1文字おき)
部分文字列の抽出
email = "user@example.com"
username = email[:email.index("@")]
domain = email[email.index("@")+1:]
print(f"ユーザー名: {username}") # user
print(f"ドメイン: {domain}") # example.com
6. タプルでのスライス
coordinates = (10, 20, 30, 40, 50, 60)
print(coordinates[1:4]) # (20, 30, 40)
print(coordinates[::2]) # (10, 30, 50)
print(coordinates[::-1]) # (60, 50, 40, 30, 20, 10)
7. スライスを使った代入操作
リスト要素の置換
numbers = [1, 2, 3, 4, 5, 6]
numbers[1:4] = [20, 30, 40]
print(numbers) # [1, 20, 30, 40, 5, 6]
要素の挿入
data = [1, 2, 5, 6]
data[2:2] = [3, 4] # インデックス2の位置に挿入
print(data) # [1, 2, 3, 4, 5, 6]
要素の削除
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
del numbers[2:5] # インデックス2〜4を削除
print(numbers) # [1, 2, 6, 7, 8]
8. 2次元リストでのスライス
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
]
print(matrix[1]) # [5, 6, 7, 8](2行目)
print(matrix[0:2]) # [[1, 2, 3, 4], [5, 6, 7, 8]](1〜2行目)
# 列の取得(リスト内包表記と組み合わせ)
column = [row[1] for row in matrix]
print(column) # [2, 6, 10](2列目)
9. slice()オブジェクトの活用
slice()オブジェクトの作成
data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# slice()オブジェクトを作成
s = slice(2, 8, 2)
print(data[s]) # [2, 4, 6]
# 名前付きスライス
HEADER = slice(0, 5)
BODY = slice(5, -2)
FOOTER = slice(-2, None)
content = list(range(20))
print(content[HEADER]) # [0, 1, 2, 3, 4]
print(content[BODY]) # [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]
print(content[FOOTER]) # [18, 19]
10. スライスのコピー操作
浅いコピー(shallow copy)
original = [1, 2, 3, 4, 5]
copy1 = original[:] # スライスによるコピー
copy2 = original.copy() # copy()メソッド
copy3 = list(original) # list()コンストラクタ
print(copy1) # [1, 2, 3, 4, 5]
print(id(original) == id(copy1)) # False(異なるオブジェクト)
11. 条件付きスライス
動的なスライス
def get_slice(data, condition):
if condition == "first_half":
return data[:len(data)//2]
elif condition == "last_half":
return data[len(data)//2:]
elif condition == "even_indices":
return data[::2]
else:
return data
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
print(get_slice(numbers, "first_half")) # [1, 2, 3, 4]
print(get_slice(numbers, "even_indices")) # [1, 3, 5, 7]
12. パフォーマンス最適化
大きなデータでのメモリ効率
# メモリ効率的な処理
def process_chunks(data, chunk_size=1000):
for i in range(0, len(data), chunk_size):
chunk = data[i:i+chunk_size]
yield chunk # ジェネレータで逐次処理
# 使用例
large_data = list(range(10000))
for chunk in process_chunks(large_data):
# チャンクごとに処理
pass
13. スライスを使った高度なテクニック
文字列の回文判定
def is_palindrome(text):
cleaned = text.lower().replace(" ", "")
return cleaned == cleaned[::-1]
print(is_palindrome("A man a plan a canal Panama")) # True
リストのローテーション
def rotate_list(lst, n):
"""リストをn個分右にローテーション"""
if not lst:
return lst
n = n % len(lst)
return lst[-n:] + lst[:-n]
data = [1, 2, 3, 4, 5]
print(rotate_list(data, 2)) # [4, 5, 1, 2, 3]
14. エラーハンドリング
安全なスライス操作
def safe_slice(data, start=None, stop=None, step=None):
"""範囲外エラーを防ぐ安全なスライス"""
if not data:
return []
length = len(data)
start = 0 if start is None else max(0, min(start, length))
stop = length if stop is None else max(0, min(stop, length))
step = 1 if step is None else step
return data[start:stop:step]
# 使用例
data = [1, 2, 3]
print(safe_slice(data, 0, 10)) # [1, 2, 3](範囲外でもエラーなし)
print(safe_slice([], 0, 5)) # [](空リストでもエラーなし)
15. NumPyとの比較
# Pythonリスト
py_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(py_list[2:8:2]) # [3, 5, 7]
# NumPy配列(参考)
# import numpy as np
# np_array = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
# print(np_array[2:8:2]) # [3 5 7]
16. 実用的な応用例
ログファイルの解析
def parse_log_lines(lines):
"""ログファイルから特定の情報を抽出"""
results = []
for line in lines:
if line.startswith("[ERROR]"):
timestamp = line[8:27] # タイムスタンプ部分
message = line[28:] # メッセージ部分
results.append((timestamp, message))
return results
log_lines = [
"[ERROR] 2024-01-15 10:30:25 Database connection failed",
"[INFO] 2024-01-15 10:30:26 Retrying connection",
"[ERROR] 2024-01-15 10:30:30 Connection timeout"
]
errors = parse_log_lines(log_lines)
print(errors)
データの前処理
def clean_data(data):
"""データの前処理:外れ値を除去"""
sorted_data = sorted(data)
n = len(sorted_data)
# 上下5%を除去
start_idx = n // 20
end_idx = n - (n // 20)
return sorted_data[start_idx:end_idx]
raw_data = [1, 2, 3, 100, 4, 5, 6, 7, 8, 200, 9, 10]
cleaned = clean_data(raw_data)
print(cleaned) # [2, 3, 4, 5, 6, 7, 8, 9]
17. スライス記法のベストプラクティス
可読性を重視したコード
# 悪い例:マジックナンバー
data = "2024-01-15,John,Engineer,50000"
name = data[11:15]
# 良い例:意味のある変数名
DATE_END = 10
NAME_START = 11
NAME_END = data.index(",", NAME_START)
name = data[NAME_START:NAME_END]
# さらに良い例:slice()オブジェクト
DATE_SLICE = slice(0, 10)
NAME_SLICE = slice(11, data.index(",", 11))
date = data[DATE_SLICE]
name = data[NAME_SLICE]
18. デバッグとテスト
def debug_slice(sequence, slice_obj):
"""スライス操作のデバッグ支援"""
start, stop, step = slice_obj.indices(len(sequence))
print(f"Original: {sequence}")
print(f"Slice: [{start}:{stop}:{step}]")
print(f"Result: {sequence[slice_obj]}")
return sequence[slice_obj]
# 使用例
data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
result = debug_slice(data, slice(2, -2, 2))
まとめ
Pythonのスライス記法は、シーケンス型データを効率的に操作するための強力な機能です。基本的な使い方から、slice()オブジェクトを使った高度なテクニック、パフォーマンスを考慮した実装まで、様々な場面で活用できます。
特に、大きなデータセットを扱う際や、文字列処理、リスト操作において、スライス記法を適切に使用することで、コードの可読性と効率性を大幅に向上させることができます。エラーハンドリングも含めて、安全で保守性の高いコードを書くことを心がけましょう。
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座
