2017-05-09 11 views
1

タプルのリストがあります。各タプルはキー値のペアであり、キーは数値であり、値は文字列です。各キーについて、上位2文字とその数をリスト形式で返す必要があります。タプルの組み合わせからトップカウントを取得

例えば、リスト

[(1, "aabbc"), (1, "babdea"), (2, "aabacc"), (2, "acdad")] 

所定のキーが1と2であり、値がタプルフォーム

(1, {"a":2, "b":2, "c":1}),(1,{"a":2, "b":2, "d":1,"e":1})...(2,{"a":2, "c":1, "d":2}) 
のタプルに変換することができる

"aabbc", "babdea", ..., "acdaad" 

ありますキー1の場合は

、結合タプルは

(1,{"a":4, "b":4, "c":1, "d":1,"e":1}) 

ので、そのカウントの上位2つの文字は、プロセスが各キー

のために繰り返される

[("a",4),("b",4)] 

だろう、私は私の所望の出力を得ることができたが、私はより良い探していますソリューション

from collections import Counter 
l=[(x[0],list(x[1])) for x in [(1, "aabbc"), (1, "babdea"), (2, "aabacc"), (2, "acdad")]] 
l2=[(y[0],Counter(y[1])) for y in l] 

l3=[(x[0][1],x[1][1]) for x in it.combinations(l2,2) if x[0][0]==x[1][0] ] 

l4=[] 
for t,y in l3: 
    d={} 
    l5=list(set(t.keys()).union(y.keys())) 
    for i in l5: 
     d[i]=t[i]+y[i] 
    d_sort=sorted(d.items(), key=lambda x: x[1], reverse=True)[:2] 

    l4.append(d_sort) 


print l4 
[[('a', 4), ('b', 4)], [('a', 5), ('c', 3)]] 
+0

キーでソートされたリストですか? – dawg

答えて

2

ます。また、文字をカウントし、最も一般的な二つの文字を抽出し、その後、同じキーを持つデ文字列を連結することができます。

import collections 

data = [(1, "aabbc"), (1, "babdea"), (2, "aabacc"), (2, "acdad")] 

groups = collections.defaultdict(str) 
for i, s in data: 
    groups[i] += s 

print([collections.Counter(string).most_common(2) 
     for string in groups.values()]) 

あなたが得られます。

[[('a', 4), ('b', 4)], [('a', 5), ('c', 3)]] 
+0

これを書いた... – dawg

0

私が使用したいiteratinながら更新されCounter Sを保持しているdefaultdictタプルのリストを通じてグラム:

>>> from collections import Counter, defaultdict 
>>> data = [(1, "aabbc"), (1, "babdea"), (2, "aabacc"), (2, "acdad")] 
>>> 
>>> result = defaultdict(Counter) 
>>> for num, letters in data: 
...  result[num].update(letters) 
... 
>>> result 
defaultdict(<class 'collections.Counter'>, {1: Counter({'a': 4, 'b': 4, 'c': 1, 'e': 1, 'd': 1}), 2: Counter({'a': 5, 'c': 3, 'd': 2, 'b': 1})}) 

二つの最も一般的な手紙を得るために、Counterオブジェクトが役に立つmost_common方法を持っています。

かなり良好
>>> {k:v.most_common(2) for k,v in result.items()} 
{1: [('a', 4), ('b', 4)], 2: [('a', 5), ('c', 3)]} 
+0

を実行し、 'Counter.most_common(2)'を使って各カウンタの最も一般的な文字を取得することができます。 –

+0

@LaurentLAPORTE私はそれを見落とした、はい。 OPがすべてのCoutnerからの最も一般的な要素をすべて望んでいるので、もう少し複雑です。それに取り組んで... – timgeb

+1

彼は2つの最も多くのコモンズを望んでいます: '[c.most_common(2)forcのresult.values()]' –

0

ないが、はるかに短い:

from itertools import groupby 
from collections import Counter 


lst = [(1, "aabbc"), (1, "babdea"), (2, "aabacc"), (2, "acdad")] 

[Counter(''.join(list(zip(*y[1]))[1])).most_common(2) for y in groupby(lst, key=lambda x: x[0])] 

# [[('a', 4), ('b', 4)], [('a', 5), ('c', 3)]] 

私はこのことができます願っています。

0

あなたのリストではない場合ソートされた、私はどうなる:それはすでにソートされている場合は

from collections import Counter 
di={} 
for i, s in data: 
    di.setdefault(i, Counter()) 
    di[i]+=Counter(s) 

print [c.most_common(2) for _,c in sorted(di.items())] 

は、あなたがgroupby使用することができますD reduce

from itertools import groupby 
li=[] 
for k, g in groupby(data, key=lambda t: t[0]): 
    li.append(reduce(lambda x,y: x+y, (Counter(t[1]) for t in g)).most_common(2)) 

print li  

いずれの場合も、印刷物:

[[('a', 4), ('b', 4)], [('a', 5), ('c', 3)]] 
関連する問題