2012-08-06 10 views
2

정렬 된 데이터 집합을 반복해야합니다. 정렬 된 모든 특성을 해당 특성에 대해 동일한 값을 갖는 청크로 그룹화합니다. 그런 다음 그 결과에 대해 몇 가지 작업을 수행합니다.for 루프 내에서 데이터 그룹화

죄송합니다 그 예는 아마 내가 뭘하는지 설명하는 더 좋은 방법이며, 약간의 혼란 :

내가 "데이터"를 제외하고이 같은 구조있어 데이터 집합을 가지고 문자열은 실제로 객체와 많이 포함 다른 데이터의. 데이터가 4 가지 기능으로 분류받을 수 있도록

[ [1, "data1"], [1, "data2"], [2, "moredata"], [2, "stuff"], 
    [2, "things"], [2, "foo"], [3, "bar"], [4, "baz"] ] 

내가 일이 원하는 것은 것은 호출

last_id = None 
grouped_data = [] 

for row in dataset: 
    id = row[0] 
    data = row[1] 

    if last_id != id: 
     # we're starting a new group, process the last group 
     processs_data(last_id, grouped_data) 
     grouped_data = [] 
    last_id = id 
    grouped_data.append(data) 

if grouped_data: 
    # we're done the loop and we still have a last group of data to process 
    # if there was no data in the dataset, grouped_data will still be empty 
    # so we won't accidentally process any empty data. 
    process_data(last_id, grouped_data) 
:

내가 끝낼 무엇
process_data(1, ["data1", "data2"]) 
process_data(2, ["moredata", "stuff", "things", "foo"]) 
process_data(3, ["bar"]) 
process_data(4, ["baz"]) 

이런 식으로 뭔가를 보이는 구조입니다

작동하지만 어색해 보입니다. 특히 last_id 변수뿐만 아니라 루프 이후 process_data에 대한 두 번째 호출로 모든 것을 추적 할 필요가 있습니다. 더 우아하고 똑똑한 솔루션을 제안 할 수있는 사람이 있는지 알고 싶습니다.

내 언어는 Python이지만 일반적인 해결책이 좋습니다.

답변

5

itertools.groupby 당신이 원하는 것입니다 :

>>> data = [ [1, "data1"], [1, "data2"], [2, "moredata"], [2, "stuff"], 
... [2, "things"], [2, "foo"], [3, "bar"], [4, "baz"] ] 
>>> 
>>> from itertools import groupby 
>>> from operator import itemgetter 
>>> 
>>> def process_data(key, keydata): 
...  print key, ':', keydata 
... 
>>> for key,keydata in groupby(data, key=itemgetter(0)): 
... process_data(key, [d[1] for d in keydata]) 
... 
1 : ['data1', 'data2'] 
2 : ['moredata', 'stuff', 'things', 'foo'] 
3 : ['bar'] 
4 : ['baz'] 

는 패스에 정렬 된 목록 및 주요 기능을 GROUPBY 그룹 목록의 각 항목 내에서 무엇. 생성 된 process_data 메소드로 전달되는 것처럼 생성자는 (key,itemgenerator) 쌍으로 되돌아갑니다.

+0

완벽합니다. 언제나 그렇듯이 파이썬에는 모든 배터리가 포함되어 있습니다. 단지 어디에 있느냐 만 찾는 것입니다. 이것에 올바른 방향으로 나를 가리켜 주셔서 감사합니다! – cecilkorik

3

itertools.groupby을 살펴보십시오. 이 경우 그룹 키에 따라 목록이 이미 정렬되어 있어야합니다 (예제 데이터가 있으므로 괜찮아요).

3

예를 들어 brownie 또는 werkzeug 패키지에서 MutliDict를 사용할 수 있습니다.

from brownie.datastructures import MultiDict 
data = [ [1, "data1"], [1, "data2"], [2, "moredata"], [2, "stuff"], 
     [2, "things"], [2, "foo"], [3, "bar"], [4, "baz"] ] 
for key, keydata in MultiDict(data).iterlists(): 
    process_data(key, keydata) 
관련 문제