たくさん寝太郎の寝床

料理とITと皿回しが好きなオタクのブログ

Pythonでindexのリストを与えてリストから複数の要素を削除する話

こんにちは、たくさん寝太郎です。

以下のような日時のリストが与えられた時に日時の間隔が一定時間以下のものを取り除きたくなりました。
例えばこの場合だと03-27と03-29の2つです。

time_list =
['2018-03-21 08-05-21',
 '2018-03-22 08-02-54',
 '2018-03-27 07-08-06',
 '2018-03-27 07-08-07',
 '2018-03-28 07-30-52',
 '2018-03-29 10-20-37',
 '2018-03-29 10-20-42',
 '2018-03-30 07-03-47']

リストから複数の要素を削除する方法だけ知りたい方は下の方の本題まで読み飛ばしてもらって構いません。


まずはdatetime型に変換します。

from datetime import datetime as dt
datetime_list = [dt.strptime(t, '%Y-%m-%d %H-%M-%S') for t in time_list]

->

[datetime.datetime(2018, 3, 21, 8, 5, 21), 
 datetime.datetime(2018, 3, 22, 8, 2, 54),
 datetime.datetime(2018, 3, 27, 7, 8, 6),
 datetime.datetime(2018, 3, 27, 7, 8, 7),
 datetime.datetime(2018, 3, 28, 7, 30, 52),
 datetime.datetime(2018, 3, 29, 10, 20, 37),
 datetime.datetime(2018, 3, 29, 10, 20, 42),
 datetime.datetime(2018, 3, 30, 7, 3, 47)]

次に、それぞれ1つ前の要素との差分を計算します。
この時一番最初の要素は最後の要素との差分が計算されるためスライスしておきます。

diff_time = []
for idx, d_time in enumerate(datetime_list):
    diff_time.append(d_time - datetime_list[idx-1])

'''
diff_timeは以下の様になる
-9 days, 1:01:34
23:57:33
4 days, 23:05:12
0:00:01
1 day, 0:22:45
1 day, 2:49:45
0:00:05
20:43:05
'''

diff_time = diff_time[1:]

次に求めた差分のリストから差分が一定時間以下のもののindexを取得します。

del_idx = [idx+1 for idx, diff in enumerate(diff_time) if diff.seconds < 10]

->

[3,6]

本題

indexのリストを与えて、リストから複数の要素を削除します。
リストから要素を取り除くのにはpop, remove, delがよく使われると思いますが、今回は内包表記で対応しました。

[t for idx, t in enumerate(time_list) if idx not in del_idx]

->

['2018-03-21 08-05-21',
 '2018-03-22 08-02-54',
 '2018-03-27 07-08-06',
 '2018-03-28 07-30-52',
 '2018-03-29 10-20-37',
 '2018-03-30 07-03-47']

無事03-27と03-29の2つが取り除かれました。

追記

記事を公開した1分後に以下の方が楽なことに気付きました。

## diff_timeをスライスしない
diff_time = []
for idx, d_time in enumerate(datetime_list):
    diff_time.append(d_time - datetime_list[idx-1])

[t for t, diff in zip(time_list, diff_time) if diff.seconds > 10]

->

['2018-03-21 08-05-21',
 '2018-03-22 08-02-54',
 '2018-03-27 07-08-06',
 '2018-03-28 07-30-52',
 '2018-03-29 10-20-37',
 '2018-03-30 07-03-47']


おわり