2011-11-11 3 views
16

거대한 튜플 목록이이 형식으로 있습니다. 각 튜플의 두 번째 필드는 카테고리 필드입니다.튜플 목록을 동일한 튜플 필드의 하위 목록으로 분할합니다.

[(1, 'A', 'foo'), 
    (2, 'A', 'bar'), 
    (100, 'A', 'foo-bar'), 

    ('xx', 'B', 'foobar'), 
    ('yy', 'B', 'foo'), 

    (1000, 'C', 'py'), 
    (200, 'C', 'foo'), 
    ..] 

동일한 카테고리 (A, B, C 등)의 하위 목록으로 분류하는 가장 효율적인 방법은 무엇입니까?

+0

[하위 목록을 새 하위 목록으로 정렬 하시겠습니까?] (http://stackoverflow.com/questions/71140) 383/sorting-sub-lists-into-new-sub-lists) – agf

답변

22

사용 itertools.groupby :

[list(group) for key,group in itertools.groupby(data,operator.itemgetter(1))] 

:

import itertools 
import operator 

data=[(1, 'A', 'foo'), 
    (2, 'A', 'bar'), 
    (100, 'A', 'foo-bar'), 

    ('xx', 'B', 'foobar'), 
    ('yy', 'B', 'foo'), 

    (1000, 'C', 'py'), 
    (200, 'C', 'foo'), 
    ] 

for key,group in itertools.groupby(data,operator.itemgetter(1)): 
    print(list(group)) 

가 하위 목록으로 각 그룹에 하나 개의 목록을 작성,

[(1, 'A', 'foo'), (2, 'A', 'bar'), (100, 'A', 'foo-bar')] 
[('xx', 'B', 'foobar'), ('yy', 'B', 'foo')] 
[(1000, 'C', 'py'), (200, 'C', 'foo')] 

을 산출 또는, 당신은 지능형리스트를 사용할 수 있습니다

세모 itertools.groupby에 대한 nd 인수는 itertools.groupbydata (첫 번째 인수)의 각 항목에 적용되는 함수입니다. key을 반환 할 것으로 예상됩니다. itertools.groupby 다음 동일한 key 가진 모든 인접 항목을 함께 그룹화합니다.

operator.itemgetter(1)은 순서대로 두 번째 항목을 선택합니다. 예를 들어

,

row=(1, 'A', 'foo') 

다음

operator.itemgetter(1)(row) 

'A'와 동일한 지 어떤지를 판정합니다. @eryksun이 코멘트에 지적한 것처럼 튜플의 종류는 어떤 임의의 순서로 표시하는 경우


, 다음, 먼저 itertools.groupby을 적용하기 전에 data를 정렬해야합니다. itertools.groupy은 동일한 키를 가진 연속적인 항목 만 그룹으로 수집하기 때문입니다.

는 부문별로 튜플을 정렬하려면 사용

data2=sorted(data,key=operator.itemgetter(1)) 
+6

데이터를 먼저 정렬해야한다는 것을 잊지 마십시오.'data2 = sorted (data, key = operator.itemgetter (1))'. – eryksun

+1

매우 명확한 답변을 보내 주셔서 감사합니다. –

+0

훌륭한 답은 lambda에 익숙한 사람들에게 연산자 대신 람다를 사용할 수 있다는 것을 잊지 마십시오. – jwg

1

는 튜플의 목록에서 싱글의 여러 목록을 얻으려면 :

foo = ((1,2), (3, 4), (5, 6), (7,8) , (9, 10)) 
[[z[i] for z in foo] for i in (0,1)] 

당신이 싱글의 여러 튜플을 얻을 것을 선호하는 경우 :

zip(*[(1,4),(2,5),(3,6)])