2017-05-09 1 views
1

튜플 목록이 있습니다. 각 튜플은 키 값 쌍이며 키는 숫자이고 값은 문자 문자열입니다. 각 키에 대해 상위 2 자와 그 수를 목록 형식으로 반환해야합니다. 목록 주어진 예튜플 조합에서 최상위 수를 얻습니다.

,

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

키는 1, 2이고 값

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

튜플

폼의 튜플로 변환 될 수있다

(1, {"a":2, "b":2, "c":1}),(1,{"a":2, "b":2, "d":1,"e":1})...(2,{"a":2, "c":1, "d":2}) 
키 1의 경우

인 경우 결합 된 튜플은

가됩니다.
(1,{"a":4, "b":4, "c":1, "d":1,"e":1}) 

16,그렇게 자신의 카운트와 상위 두 문자는 프로세스가 내가 원하는 출력을 얻을 수 있었다 각 키

에 대해 반복 될 것이다

[("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의를 보유하고 defaultdict 튜플의 목록을 통해 g는 : 가장 일반적인 두 글자를 얻기 위하여

>>> 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

그는 두 개의 가장 많은 커먼을 원합니다 :'result.values ​​()에서 c를위한 c.most_common (2) ' –

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)]] 
관련 문제