23248


python(2.7.10)で，list内の検索をする際

> In[1]: a = [1,2,3,3,3,4,5]  
>  In[2]: a.index(3)  
>  Out[2]: 2

と最初のインデックスが返ってきます．  
理想は[2,3,4]と全ての該当インデックスが欲しいのですが，簡単な書き方で取得できる方法はありませんか．

今のところ可能な限り要素を検索しつつ取得した場所を取り除き続けるという力技をしていますがもう少し簡潔でメモリに優しい方法はないでしょうか  
(元のリストはそのままにしておきたいのでdeepcopyをしていますがメモリを食ってしまうようで大きいリストで大量に実行すると止まってしまいます…)

[code]

    from copy import deepcopy
    b = deepcopy(a)
    ans = []
    while True:
      try:   
        ans.append(b.index(3))
        b.pop(b.index(3))
      except:
        break
    
[/code]


CC BY-SA 3.0
2016-03-18T07:11:01.753
23246
2016-04-11T13:20:29.397
12962
question
python
pythonのリスト内の重複要素検索


単純にforで

[code]

    ans = []
    for index, value in enumerate(a):
        if value == 3:
            ans.append(index)
    
[/code]

* * *

内包表記で

[code]

    ans = [ i for i, v in enumerate(a) if v == 3]
    
[/code]


CC BY-SA 3.0
2016-03-18T07:30:35.700
23248
2016-03-18T08:41:31.943
2016-03-18T08:41:31.943
5044
5044
23246
answer


巨大なリストを扱うのであれば、イテレータが望ましいと思います。

ビルトインの`list`からサブクラス`ext_list`を設け、`indices`メソッドをジェネレータとして実装してはどうでしょうか。

[code]

    #!/usr/bin/python
    # -*- coding: utf8 -*-
    
    class ext_list(list):
        def indices(self, v):
            for i, elm in enumerate(self):
                if elm is v:
                    yield i
    
    from pprint import pprint
    
    a = ext_list([1, 2, 3, 3, 3, 4, 5])
    pprint(list(a.indices(3)))
    
[/code]

結果:

[code]

    [2, 3, 4]
    
[/code]

もちろんメモリを気にするのであれば、この結果の後処理もイテレータで扱う必要があるのですが。


CC BY-SA 3.0
2016-03-18T12:52:58.350
23259
2016-03-18T12:52:58.350
62
23246
answer


numpyのnp.whereを使う方法はどうでしょうか。

[code]

    In [1]: import numpy as np
    
    In [2]: a = [1,2,3,3,3,4,5]
    
    In [3]: np.where(map(lambda x: x == 3, a))
    Out[3]: (array([2, 3, 4]),)
    
[/code]


CC BY-SA 3.0
2016-04-11T13:20:29.397
23921
2016-04-11T13:20:29.397
808
23246
answer