Pythonで連続する同じ値の要素をサブリストにまとめる方法
数値のリスト nums が与えられたとき、同じ値が連続して並んでいる要素をひとつのサブリストにまとめてパックするプログラムを作成します。ここで注意すべき点は、リスト内に1回しか出現しない要素であっても、それ単独のサブリストとして残す必要があるということです。
たとえば、入力が nums = [5, 5, 2, 7, 7, 7, 2, 2, 2, 2] の場合、出力は次のようになります。
[[5, 5], [2], [7, 7, 7], [2, 2, 2, 2]]
同じ値でも離れて登場する場合は別々のサブリストになるため、2 が2箇所に分かれている点に注目してください。
解き方の手順
numsが空の場合は、空のリストを返すresultを、先頭要素nums[0]を含むリストで初期化する(つまり[[nums[0]]])- インデックス
jを 0 に設定する - i を 1 から
numsのサイズまで繰り返す:nums[i]が直前の要素nums[i - 1]と異なる場合resultの末尾に新しい空のリストを追加するjを 1 増やす
nums[i]をresult[j]の末尾に追加する
resultを返す
実装例
それでは、上記の手順を実際のコードで確認してみましょう。
class Solution: def solve(self, nums): if not nums: return [] result = [[nums[0]]] j = 0 for i in range(1, len(nums)): if nums[i] != nums[i - 1]: result.append([]) j += 1 result[j].append(nums[i]) return result ob = Solution() nums = [5, 5, 2, 7, 7, 7, 2, 2, 2, 2] print(ob.solve(nums))
入力
[5, 5, 2, 7, 7, 7, 2, 2, 2, 2]
出力
[[5, 5], [2], [7, 7, 7], [2, 2, 2, 2]]
itertools.groupbyを使ったより簡潔な方法
Pythonの標準ライブラリ itertools.groupby を使うと、同じ処理をわずか数行で実現できます。groupbyは「隣接する同じキーの要素」をグループ化する関数なので、この問題にぴったりです。
from itertools import groupby def solve(nums): return [list(group) for _, group in groupby(nums)] nums = [5, 5, 2, 7, 7, 7, 2, 2, 2, 2] print(solve(nums)) # 出力: [[5, 5], [2], [7, 7, 7], [2, 2, 2, 2]]
どちらの方法でも計算量は O(n) で、リストを一度走査するだけで済みます。自前でループを書きたい場合は最初の方法、可読性と簡潔さを重視する場合は groupby を使う方法がおすすめです。
-
Pythonでリスト内の連続する偶数要素を交換する方法
問題の概要数値のリスト nums が与えられたとき、「連続して現れる偶数」同士をペアごとに入れ替えることを考えます。たとえば、入力が nums = [4, 5, 6, 8, 10] の場合、出力は [6, 5, 4, 10, 8] となります。解法のアプローチこの問題は、一時変数を1つ用意するだけでシンプルに解決できます。手順は以下の通りです。一時変数 temp を None で初期化するi を 0 からリストの要素数まで順にループさせるnums[i] が偶数(2で割った余りが0)の場合:temp が None でなければ、nums[i] と nums[temp] を交換し、temp を No
-
Pythonのリストで連続する要素をペアにする方法
Pythonでデータ分析を行っていると、リスト内の隣接する(連続する)要素同士をペアとして取り出したい場面に出会うことがあります。本記事では、この処理を実現するための代表的な2つの方法を、サンプルコードとともにわかりやすく解説します。インデックスとrangeを組み合わせる方法まずは、リストの連続するインデックスを組み合わせてペアを作る式を設計する方法です。range関数に「リストの長さ − 1」を渡すことで、ペアリングを繰り返す最大回数を決定します。これにより、最後の要素にアクセスする際に範囲外エラーが発生するのを防いでいます。サンプルコードlistA = [51,23,11,45] # 対象