質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

5回答

791閲覧

Pythonでリストを条件を使って複数のリストにしたい

teraterakoya

総合スコア8

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/08/25 05:50

困っていること

ログの集計を実装しており、表示とクリックに関するログをクリックログをもとに分割したいです
具体的には[show, show, click, show, show, show] のようなリストを
[[show, show, click], [show, show, show]]としたいです
膨大な量のログなのでできるだけ早いアルゴリズムでやるか、ビルトインのライブラリを使ってうまくやりたいですが、
現状はナイーブな実装しか思い浮かんでいません

ナイーブな実装

ナイーブな実装を考えると以下のようになります

python

1def iikanji(l, stop_word): 2 r = [] 3 tmp = [] 4 for _l in l: 5 tmp.append(_l) 6 if _l == stop_word: 7 r.append(tmp) 8 tmp = [] 9 r.append(tmp) 10 return r 11 12s = 'show' 13c = 'click' 14l = [s, s, c, s, s, s] 15iikanji(l) # => [[s, s, c], [s, s, s]]

なにかアイデアありませんでしょうか
どうぞよろしくお願いします

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

clickが存在する位置のインデックスのリストを予め作っておき、それを元に分割する方法です。

jeanbiegoさんの処理をお借りし、私の処理も時間を測ってみました。
またjeanbiegoさんの生成リストだとclickが少ないように思えたので、
パターンではありますが、clickが多めのリストを生成して計測しました。

python

1import time 2 3def iikanji(l, stop_word): 4 r = [] 5 tmp = [] 6 for _l in l: 7 tmp.append(_l) 8 if _l == stop_word: 9 r.append(tmp) 10 tmp = [] 11 r.append(tmp) 12 return r 13 14def index_word(l, stop_word): 15 stop = l.index(stop_word)+1 16 return [l[:stop],l[stop:]] 17 18s = 'show' 19c = 'click' 20l = [c if i % 3 == 0 else s for i in range(10000)] 21 22start = time.time() 23for i in range(1000): 24 iikanji(l,c) 25elapsed_time = time.time() - start 26print ("iikanji_time:{0}".format(elapsed_time) + "[sec]") 27# iikanji_time:3.5083327293395996[sec] 28 29start = time.time() 30for i in range(1000): 31 index_word(l,c) 32elapsed_time = time.time() - start 33print ("index_time: {0}".format(elapsed_time) + "[sec]") 34# index_time: 0.025966882705688477[sec] 35 36start = time.time() 37il = [i for i, v in enumerate(l) if v == c] 38idx = 0 39rl = [] 40for s in il: 41 rl.append(l[idx:s+1]) 42 idx = s+1 43if idx < len(l): rl.append(l[idx:]) 44elapsed_time = time.time() - start 45print ("index_list_time: {0}".format(elapsed_time) + "[sec]") 46# index_list_time: 0.0039975643157958984[sec] 47

投稿2020/08/25 07:07

編集2020/08/25 07:40
yureighost

総合スコア2183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

こんにちは

空のリストを作って、それに要素をひとつずつappendする替わりに、元のリストのスライスをyieldするジェネレータを作り、リスト化は最後に行うことにするのはいかがでしょうか?

以下は、この考え方によるサンプルです。

python

1def divide(l, stop_word): 2 while True: 3 stop_index = l.index(stop_word) + 1 if stop_word in l else -1 4 yield l[:stop_index] if stop_index >= 0 else l 5 if stop_index == -1: 6 break 7 l = l[stop_index:] 8 9 10result = list(divide(l, c))

投稿2020/08/25 06:56

jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

どのくらいの速さを求められてるのか不明ですが、たとえば下記のような…?

python3

1import time 2 3def iikanji(l, stop_word): 4 r = [] 5 tmp = [] 6 for _l in l: 7 tmp.append(_l) 8 if _l == stop_word: 9 r.append(tmp) 10 tmp = [] 11 r.append(tmp) 12 return r 13 14def index_word(l, stop_word): 15 stop = l.index(stop_word)+1 16 return [l[:stop],l[stop:]] 17 18s = 'show' 19c = 'click' 20l = [s]*1000+[c]+[s]*1999 21 22start = time.time() 23for i in range(1000): 24 iikanji(l,c) # => [[s, s, c], [s, s, s]] 25elapsed_time = time.time() - start 26print ("iikanji_time:{0}".format(elapsed_time) + "[sec]") 27# iikanji_time:0.8487265110015869[sec] 28 29start = time.time() 30for i in range(1000): 31 index_word(l,c) # => [[s, s, c], [s, s, s]] 32elapsed_time = time.time() - start 33print ("index_time: {0}".format(elapsed_time) + "[sec]") 34# index_time: 0.04487943649291992[sec]

投稿2020/08/25 06:14

jeanbiego

総合スコア3966

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

奇妙な手法を考えました

python

1def func(l, s, c): 2 out = [(i+c).lstrip(',').split(',') for i in ','.join(l).split(c)] 3 if l[-1] == c: 4 out = out[:-1] 5 else: 6 out[-1][-1] = s 7 return out 8 9s = 'show' 10c = 'click' 11l = [s, s, c, s, s, s] 12 13func(l, s, c) 14# [['show', 'show', 'click'], ['show', 'show', 'show']] 15func([s, s, c, s, s, s, c], s, c) 16# [['show', 'show', 'click'], ['show', 'show', 'show', 'click']]

投稿2020/08/26 01:49

kirara0048

総合スコア1399

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

そのように分割しないで、元のリストのままで処理することを考えた方が良い気がします。
インデックスを適切に保持すれば出来るのでは?

(こういう処理は、Rubyだと一発ですが)

投稿2020/08/25 07:45

otn

総合スコア84555

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問