「リストから2つおきに要素を取り出したい」
「文字列を逆順にしたい」
「配列の一部を間引いて処理したい」
このような場面で便利なのが、Pythonのスライス機能の「ステップ(step)」指定です。
ステップを使うことで、規則的な間引きや逆順の処理が、とても簡単に書けるようになります。
この記事では、スライスのステップ機能について、基本的な使い方から応用例、注意点まで、初心者の方にもわかりやすく解説します。
スライスの基本構文とステップの位置

スライスの完全な構文
Pythonのスライスは、次の形式で書きます:
sequence[start:stop:step]
start
:開始位置(省略可能)stop
:終了位置(省略可能)step
:取り出す間隔(省略可能、デフォルトは1)
最初の例:2つおきに取り出す
text = "abcdefgh"
result = text[::2]
print(f"元の文字列: {text}")
print(f"2つおき: {result}")
実行結果:
元の文字列: abcdefgh
2つおき: aceg
::2
は「最初から最後まで、2つおきに取り出す」という意味です。
ステップなしとの比較
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(f"元のリスト: {numbers}")
print(f"普通のスライス: {numbers[2:8]}") # [2, 3, 4, 5, 6, 7]
print(f"ステップ2: {numbers[2:8:2]}") # [2, 4, 6]
print(f"ステップ3: {numbers[2:8:3]}") # [2, 5]
実行結果:
元のリスト: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
普通のスライス: [2, 3, 4, 5, 6, 7]
ステップ2: [2, 4, 6]
ステップ3: [2, 5]
正のステップ:前から順に間引く
基本的な間引きパターン
alphabet = "abcdefghijklmnop"
print(f"元の文字列: {alphabet}")
print(f"1つおき(step=1): {alphabet[::1]}") # 全て(デフォルト)
print(f"2つおき(step=2): {alphabet[::2]}") # a, c, e, g...
print(f"3つおき(step=3): {alphabet[::3]}") # a, d, g, j...
print(f"4つおき(step=4): {alphabet[::4]}") # a, e, i, m
実行結果:
元の文字列: abcdefghijklmnop
1つおき(step=1): abcdefghijklmnop
2つおき(step=2): acegikmo
3つおき(step=3): adgjm
4つおき(step=4): aeim
開始位置を指定した間引き
numbers = list(range(20)) # [0, 1, 2, ..., 19]
print(f"元のリスト: {numbers}")
print(f"0から2つおき: {numbers[0::2]}") # [0, 2, 4, 6, ...]
print(f"1から2つおき: {numbers[1::2]}") # [1, 3, 5, 7, ...]
print(f"2から3つおき: {numbers[2::3]}") # [2, 5, 8, 11, ...]
実行結果:
元のリスト: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
0から2つおき: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
1から2つおき: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
2から3つおき: [2, 5, 8, 11, 14, 17]
範囲を指定した間引き
data = "0123456789"
print(f"元のデータ: {data}")
print(f"2から8まで2つおき: {data[2:8:2]}") # インデックス2,4,6
print(f"1から9まで3つおき: {data[1:9:3]}") # インデックス1,4,7
print(f"0から10まで4つおき: {data[0:10:4]}") # インデックス0,4,8
実行結果:
元のデータ: 0123456789
2から8まで2つおき: 246
1から9まで3つおき: 147
0から10まで4つおき: 048
負のステップ:後ろから前に向かって取り出す

基本的な逆順処理
負のステップを使うと、逆方向に要素を取り出すことができます。
text = "Python"
numbers = [1, 2, 3, 4, 5]
print(f"元の文字列: {text}")
print(f"逆順: {text[::-1]}")
print(f"元のリスト: {numbers}")
print(f"逆順: {numbers[::-1]}")
実行結果:
元の文字列: Python
逆順: nohtyP
元のリスト: [1, 2, 3, 4, 5]
逆順: [5, 4, 3, 2, 1]
逆方向の間引き
alphabet = "abcdefghijklmnop"
print(f"元の文字列: {alphabet}")
print(f"逆順で全て: {alphabet[::-1]}") # 全て逆順
print(f"逆順で2つおき: {alphabet[::-2]}") # 後ろから2つおき
print(f"逆順で3つおき: {alphabet[::-3]}") # 後ろから3つおき
実行結果:
元の文字列: abcdefghijklmnop
逆順で全て: ponmlkjihgfedcba
逆順で2つおき: pnljhfdb
逆順で3つおき: pmjgda
負のステップでの範囲指定
負のステップを使うとき、開始位置と終了位置の意味が変わることに注意が必要です。
text = "0123456789"
# 正のステップ:左から右へ
print(f"2から8まで: {text[2:8]}") # "234567"
print(f"2から8まで2つおき: {text[2:8:2]}") # "246"
# 負のステップ:右から左へ
print(f"8から2まで逆順: {text[8:2:-1]}") # "876543"
print(f"8から2まで逆順2つおき: {text[8:2:-2]}") # "864"
実行結果:
2から8まで: 234567
2から8まで2つおき: 246
8から2まで逆順: 876543
8から2まで逆順2つおき: 864
実用的な使用例

偶数・奇数インデックスの分離
data = ["A", "B", "C", "D", "E", "F", "G", "H"]
# 偶数インデックス(0, 2, 4, 6...)
even_items = data[::2]
print(f"偶数インデックス: {even_items}")
# 奇数インデックス(1, 3, 5, 7...)
odd_items = data[1::2]
print(f"奇数インデックス: {odd_items}")
実行結果:
偶数インデックス: ['A', 'C', 'E', 'G']
奇数インデックス: ['B', 'D', 'F', 'H']
パスワードの簡単な暗号化・復号化
def simple_encrypt(text):
"""文字列を逆順にして暗号化"""
return text[::-1]
def simple_decrypt(encrypted):
"""暗号化された文字列を復号化"""
return encrypted[::-1]
# 暗号化・復号化の例
original = "hello123"
encrypted = simple_encrypt(original)
decrypted = simple_decrypt(encrypted)
print(f"元の文字列: {original}")
print(f"暗号化: {encrypted}")
print(f"復号化: {decrypted}")
実行結果:
元の文字列: hello123
暗号化: 321olleh
復号化: hello123
CSVデータの処理
# CSVのような形式のデータ
csv_lines = [
"名前,年齢,職業",
"田中,25,エンジニア",
"佐藤,30,デザイナー",
"鈴木,28,営業",
"高橋,32,マネージャー",
"山田,24,エンジニア"
]
print("全データ:")
for line in csv_lines:
print(line)
print("\nヘッダーを除いた奇数行のみ:")
odd_lines = csv_lines[1::2] # ヘッダー除いて奇数行
for line in odd_lines:
print(line)
print("\n逆順で表示:")
for line in csv_lines[::-1]:
print(line)
実行結果:
全データ:
名前,年齢,職業
田中,25,エンジニア
佐藤,30,デザイナー
鈴木,28,営業
高橋,32,マネージャー
山田,24,エンジニア
ヘッダーを除いた奇数行のみ:
田中,25,エンジニア
鈴木,28,営業
山田,24,エンジニア
逆順で表示:
山田,24,エンジニア
高橋,32,マネージャー
鈴木,28,営業
佐藤,30,デザイナー
田中,25,エンジニア
名前,年齢,職業
画像処理やデータ分析での間引き
# センサーデータのような数値リスト
sensor_data = list(range(100)) # 0から99までの数値
print(f"全データ数: {len(sensor_data)}")
print(f"元データの一部: {sensor_data[:10]}")
# 10個おきにサンプリング
sampled_data = sensor_data[::10]
print(f"10個おきサンプリング: {sampled_data}")
# 最後の10個を逆順で取得
last_10_reverse = sensor_data[-10:][::-1]
print(f"最後の10個を逆順: {last_10_reverse}")
# 中央部分を5つおきで取得
middle_part = sensor_data[25:75:5]
print(f"中央部分5つおき: {middle_part}")
実行結果:
全データ数: 100
元データの一部: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
10個おきサンプリング: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
最後の10個を逆順: [99, 98, 97, 96, 95, 94, 93, 92, 91, 90]
中央部分5つおき: [25, 30, 35, 40, 45, 50, 55, 60, 65, 70]
よくあるエラーと注意点

エラー1:ステップが0の場合
text = "hello"
# text[::0] # ValueError: slice step cannot be zero
エラーメッセージ:
ValueError: slice step cannot be zero
ステップに0を指定することはできません。最小値は1(または-1)です。
エラー2:負のステップでの範囲指定ミス
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 正のステップ:start < stop
print(f"正常: {numbers[2:8:1]}") # [2, 3, 4, 5, 6, 7]
# 負のステップ:start > stop である必要がある
print(f"空リスト: {numbers[2:8:-1]}") # [] (空)
print(f"正常: {numbers[8:2:-1]}") # [8, 7, 6, 5, 4, 3]
実行結果:
正常: [2, 3, 4, 5, 6, 7]
空リスト: []
正常: [8, 7, 6, 5, 4, 3]
負のステップを使うときは、開始位置が終了位置よりも大きくなければなりません。
注意3:インデックスの境界
short_list = [1, 2, 3]
# インデックスが範囲外でもエラーにならない
print(f"範囲外指定: {short_list[::10]}") # [1] (最初の要素だけ)
print(f"大きなステップ: {short_list[1::5]}") # [2] (2番目の要素だけ)
実行結果:
範囲外指定: [1]
大きなステップ: [2]
高度な使用例
文字列の回文(パリンドローム)チェック
def is_palindrome(text):
"""文字列が回文かどうかをチェック"""
# 小文字に変換して比較
clean_text = text.lower()
return clean_text == clean_text[::-1]
# テスト
test_words = ["racecar", "hello", "madam", "python", "level"]
for word in test_words:
result = is_palindrome(word)
print(f"{word}: {'回文です' if result else '回文ではありません'}")
実行結果:
racecar: 回文です
hello: 回文ではありません
madam: 回文です
python: 回文ではありません
level: 回文です
リストの並び替えと間引きの組み合わせ
# 成績データ
scores = [85, 92, 78, 96, 88, 73, 89, 94, 81, 87]
print(f"元の成績: {scores}")
# 降順にソートしてから上位3名を取得
sorted_desc = sorted(scores, reverse=True)
top_3 = sorted_desc[:3]
print(f"上位3名: {top_3}")
# 元のリストから2つおきに取得して逆順に
every_second_reverse = scores[::2][::-1]
print(f"2つおきを逆順: {every_second_reverse}")
# 最高点と最低点を除いた平均点計算用
middle_scores = sorted(scores)[1:-1] # 最低と最高を除く
average = sum(middle_scores) / len(middle_scores)
print(f"最高・最低除いた平均: {average:.1f}")
実行結果:
元の成績: [85, 92, 78, 96, 88, 73, 89, 94, 81, 87]
上位3名: [96, 94, 92]
2つおきを逆順: [81, 88, 78, 85]
最高・最低除いた平均: 87.5
二次元リストでのステップ使用
# 5x5のマトリックス
matrix = [
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
[21, 22, 23, 24, 25]
]
print("元のマトリックス:")
for row in matrix:
print(row)
print("\n1行おきに表示:")
for row in matrix[::2]:
print(row)
print("\n逆順で表示:")
for row in matrix[::-1]:
print(row)
print("\n各行の2つおき要素:")
for row in matrix:
print(row[::2])
実行結果:
元のマトリックス:
[1, 2, 3, 4, 5]
[6, 7, 8, 9, 10]
[11, 12, 13, 14, 15]
[16, 17, 18, 19, 20]
[21, 22, 23, 24, 25]
1行おきに表示:
[1, 2, 3, 4, 5]
[11, 12, 13, 14, 15]
[21, 22, 23, 24, 25]
逆順で表示:
[21, 22, 23, 24, 25]
[16, 17, 18, 19, 20]
[11, 12, 13, 14, 15]
[6, 7, 8, 9, 10]
[1, 2, 3, 4, 5]
各行の2つおき要素:
[1, 3, 5]
[6, 8, 10]
[11, 13, 15]
[16, 18, 20]
[21, 23, 25]
パフォーマンスの考慮

ステップスライス vs ループ処理
import time
# 大きなリストを作成
large_list = list(range(1000000))
# ステップスライスでの処理時間測定
start_time = time.time()
sliced_result = large_list[::2]
slice_time = time.time() - start_time
# ループでの処理時間測定
start_time = time.time()
loop_result = []
for i in range(0, len(large_list), 2):
loop_result.append(large_list[i])
loop_time = time.time() - start_time
print(f"ステップスライス: {slice_time:.4f}秒")
print(f"ループ処理: {loop_time:.4f}秒")
print(f"結果は同じ: {sliced_result == loop_result}")
一般的に、ステップスライスの方がループ処理よりも高速です。
まとめ
スライスのステップ機能は、Pythonでデータを効率的に処理するための強力な機能です。
重要なポイント
- ステップは
[start:stop:step]
の3番目の要素 - 正のステップ:前から後ろに向かって間引き
- 負のステップ:後ろから前に向かって間引き
- ステップが0だとエラーが発生
よく使うパターン
パターン | 書き方 | 結果 |
---|---|---|
全体を逆順 | seq[::-1] | 完全に逆順 |
2つおき | seq[::2] | 偶数インデックス |
1番目から2つおき | seq[1::2] | 奇数インデックス |
逆順2つおき | seq[::-2] | 後ろから2つおき |
範囲逆順 | seq[end:start:-1] | 指定範囲を逆順 |
活用場面
- データの間引き処理
- 逆順並び替え
- 偶数・奇数行の分離
- サンプリング処理
- 文字列の反転
ステップスライスを使いこなすことで、for文を使わずに済む場面が多くなり、コードがより簡潔で読みやすくなります。
まずは基本的なパターンから始めて、徐々に複雑な処理にチャレンジしてみてください。
コメント