

2つ以上同一の要素を含むリストを抽出したいです．

具体的には

[code]

    li=[[1,2,3],[2,3,4],[3,4,5],[4,5,6],[2,3,4],[1,2,3],[2,3,4],[5,6,7]]
    
[/code]

liは，[1,2,3]が2つ，[2,3,4]が3つ，[3,4,5][4,5,6][5,6,7]は1つずつ含まれており，  
2つ以上同一の要素を含むリストを抽出し，以下のli2のような結果を求めたいです．

[code]

    li2=[[1,2,3],[2,3,4]]
    
[/code]

よろしくお願いします。


CC BY-SA 3.0
2016-01-22T04:37:26.420
21171
2016-02-24T09:28:25.963
14061
question
python
Pythonで2次元リストの条件に合う要素を抽出


**方法1**  
`itertools.groupby`を使う方法。ソートして同じ要素が並んだ時はグループ化します。結果の順序は維持されません。

[code]

    from itertools import groupby
    print [k for k, g in groupby(sorted(li)) if len(list(g)) >= 2]
    
[/code]

**方法2**  
`collections.Counter`を使う方法。結果の順序は維持されません。

[code]

    import collections
    
    li=[[1,2,3],[2,3,4],[3,4,5],[4,5,6],[2,3,4],[1,2,3],[2,3,4],[5,6,7]]
    li2 = map(lambda (k,v): list(k), # タプルの部分だけ取り出して、リストに戻す
              filter(lambda (x, v): v>= 2, # Counterで数えた結果で2個以上を抽出
                     collections.Counter(
                         map(tuple, li)  # Counterで数えられるようにハッシュ可能なタプルにする
                     ).items()
              )
    )
    print li2
    
[/code]

実行結果

[code]

    [[2, 3, 4], [1, 2, 3]]
    
[/code]


CC BY-SA 3.0
2016-01-22T05:50:32.717
21176
2016-01-22T07:07:27.060
2016-01-22T07:07:27.060
7837
7837
21171
answer


Python3で動く例です。

[code]

    li=[[1,2,3],[2,3,4],[3,4,5],[4,5,6],[2,3,4],[1,2,3],[2,3,4],[5,6,7]]
    from collections import Counter
    c = Counter(map(tuple, li))
    
[/code]

最終的にli2の要素がリストでなくてもいいなら:

[code]

    li2 = list(filter(lambda x: c[x] > 1, c))
    
[/code]

リストじゃなきゃダメなら:

[code]

    li2 = list(map(list, filter(lambda x: c[x] > 1, c)))
    
[/code]

もし順序も維持したいなら:

[code]

    li2 = sorted(list(map(list, filter(lambda x: c[x] > 1, c))), key=li.index)
    
[/code]


CC BY-SA 3.0
2016-01-22T06:15:48.150
21177
2016-01-22T06:15:48.150
13227
21171
answer


すでに回答になっているのですが、mapやlambdaよりList Comprehensionの方がすっきりする気がします。

[code]

    from collections import Counter
    li=[[1,2,3],[2,3,4],[3,4,5],[4,5,6],[2,3,4],[1,2,3],[2,3,4],[5,6,7]]
    c = Counter(tuple(items) for items in li)
    more_than_one = [items for items, count in c.most_common() if count > 1]
    
[/code]

more_than_one：

> [(2, 3, 4), (1, 2, 3)]


CC BY-SA 3.0
2016-02-24T09:28:25.963
22482
2016-02-24T09:28:25.963
2314
21171
answer