문제

Python을 실제로 사용하는 방법에 대한 이해 가능한 설명을 찾지 못했습니다. itertools.groupby() 기능.내가하려는 것은 이것이다 :

  • 목록을 작성하십시오 - 이 경우에는 객관화된 자녀의 자녀입니다. lxml 요소
  • 몇 가지 기준에 따라 그룹으로 나눕니다.
  • 그런 다음 나중에 각 그룹을 개별적으로 반복합니다.

나는 검토했다 문서, 그리고 , 그러나 단순한 숫자 목록 이상으로 적용하는 데 어려움을 겪었습니다.

그럼 어떻게 사용하나요? itertools.groupby()?사용해야 하는 또 다른 기술이 있나요?좋은 "전제 조건" 읽기에 대한 조언도 감사하겠습니다.

도움이 되었습니까?

해결책

중요 사항: 당신은해야 데이터 정렬 첫 번째.


내가 얻지 못한 부분은 예제 구성에서

groups = []
uniquekeys = []
for k, g in groupby(data, keyfunc):
   groups.append(list(g))    # Store group iterator as a list
   uniquekeys.append(k)

k 현재 그룹화 키입니다. g 해당 그룹화 키로 정의된 그룹을 반복하는 데 사용할 수 있는 반복자입니다.즉, groupby 반복자 자체는 반복자를 반환합니다.

다음은 더 명확한 변수 이름을 사용하는 예입니다.

from itertools import groupby

things = [("animal", "bear"), ("animal", "duck"), ("plant", "cactus"), ("vehicle", "speed boat"), ("vehicle", "school bus")]

for key, group in groupby(things, lambda x: x[0]):
    for thing in group:
        print "A %s is a %s." % (thing[1], key)
    print " "

결과는 다음과 같습니다.

곰은 동물이다.
오리는 동물이다.

선인장은 식물이다.

쾌속정은 차량이다.
스쿨버스는 차량입니다.

이 예에서는 things 각 튜플의 첫 번째 항목이 두 번째 항목이 속한 그룹인 튜플 목록입니다.

그만큼 groupby() 함수는 두 가지 인수를 취합니다:(1) 그룹화할 데이터 및 (2) 그룹화할 기능입니다.

여기, lambda x: x[0] 말한다 groupby() 각 튜플의 첫 번째 항목을 그룹화 키로 사용합니다.

위에서 for 성명, groupby 각 고유 키에 대해 한 번씩 세 개의(키, 그룹 반복자) 쌍을 반환합니다.반환된 반복자를 사용하여 해당 그룹의 각 개별 항목을 반복할 수 있습니다.

다음은 목록 이해를 사용하여 동일한 데이터를 사용한 약간 다른 예입니다.

for key, group in groupby(things, lambda x: x[0]):
    listOfThings = " and ".join([thing[1] for thing in group])
    print key + "s:  " + listOfThings + "."

결과는 다음과 같습니다.

동물:곰과 오리.
식물:선인장.
차량:스피드보트와 스쿨버스.

다른 팁

코드를 보여주실 수 있나요?

Python 문서의 예는 매우 간단합니다.

groups = []
uniquekeys = []
for k, g in groupby(data, keyfunc):
    groups.append(list(g))      # Store group iterator as a list
    uniquekeys.append(k)

따라서 귀하의 경우 데이터는 노드 목록이고 keyfunc는 기준 함수의 논리가 이동하는 곳입니다. groupby() 데이터를 그룹화합니다.

주의하셔야 합니다 데이터를 정렬하다 전화하기 전에 기준에 따라 groupby 아니면 작동하지 않습니다. groupby 메서드는 실제로 목록을 반복하고 키가 변경될 때마다 새 그룹을 만듭니다.

groupby의 깔끔한 트릭은 길이 인코딩을 한 줄로 실행하는 것입니다.

[(c,len(list(cgen))) for c,cgen in groupby(some_string)]

첫 번째 요소는 문자이고 두 번째 요소는 반복 횟수인 2-튜플 목록을 제공합니다.

편집하다:이렇게 구분이 되니 참고하세요 itertools.groupby SQL에서 GROUP BY 의미론:itertools는 반복자를 미리 정렬하지 않으며 일반적으로 정렬할 수 없으므로 동일한 "키"를 가진 그룹은 병합되지 않습니다.

itertools.groupby 항목을 그룹화하는 도구입니다.

에서 문서, 우리는 그것이 무엇을 할 수 있는지 더 자세히 수집합니다:

# [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B

# [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D

groupby 객체는 그룹이 생성자인 키-그룹 쌍을 생성합니다.

특징

  • ㅏ.연속된 항목을 그룹화
  • 비.정렬된 반복 가능 항목이 주어지면 항목의 모든 항목을 그룹화합니다.
  • 씨.주요 기능을 사용하여 항목을 그룹화하는 방법 지정

비교

# Define a printer for comparing outputs
>>> def print_groupby(iterable, key=None):
...    for k, g in it.groupby(iterable, key):
...        print("key: '{}'--> group: {}".format(k, list(g)))

# Feature A: group consecutive occurrences
>>> print_groupby("BCAACACAADBBB")
key: 'B'--> group: ['B']
key: 'C'--> group: ['C']
key: 'A'--> group: ['A', 'A']
key: 'C'--> group: ['C']
key: 'A'--> group: ['A']
key: 'C'--> group: ['C']
key: 'A'--> group: ['A', 'A']
key: 'D'--> group: ['D']
key: 'B'--> group: ['B', 'B', 'B']

# Feature B: group all occurrences
>>> print_groupby(sorted("BCAACACAADBBB"))
key: 'A'--> group: ['A', 'A', 'A', 'A', 'A']
key: 'B'--> group: ['B', 'B', 'B', 'B']
key: 'C'--> group: ['C', 'C', 'C']
key: 'D'--> group: ['D']

# Feature C: group by a key function
>>> key = lambda x: x.islower()
>>> print_groupby(sorted("bCAaCacAADBbB"), key)
key: 'False'--> group: ['A', 'A', 'A', 'B', 'B', 'C', 'C', 'D']
key: 'True'--> group: ['a', 'a', 'b', 'b', 'c']

용도

메모:후자의 예 중 일부는 Víctor Terrón의 PyCon에서 파생되었습니다. (말하다) (스페인의), "Itertools를 사용한 새벽의 쿵푸".또한 참조하십시오 groupby소스 코드 C로 작성되었습니다.


응답

# OP: Yes, you can use `groupby`, e.g. 
[do_something(list(g)) for _, g in groupby(lxml_elements, key=criteria_func)]

다른 예시:

for key, igroup in itertools.groupby(xrange(12), lambda x: x // 5):
    print key, list(igroup)

결과

0 [0, 1, 2, 3, 4]
1 [5, 6, 7, 8, 9]
2 [10, 11]

igroup은 반복자(문서에서는 하위 반복자라고 함)입니다.

이는 생성기를 청크하는 데 유용합니다.

def chunker(items, chunk_size):
    '''Group items in chunks of chunk_size'''
    for _key, group in itertools.groupby(enumerate(items), lambda x: x[0] // chunk_size):
        yield (g[1] for g in group)

with open('file.txt') as fobj:
    for chunk in chunker(fobj):
        process(chunk)

groupby의 또 다른 예 - 키가 정렬되지 않은 경우.다음 예에서 xx의 항목은 yy의 값으로 그룹화됩니다.이 경우 0 세트 하나가 먼저 출력되고, 1 세트가 출력되고, 0 세트가 다시 출력됩니다.

xx = range(10)
yy = [0, 0, 0, 1, 1, 1, 0, 0, 0, 0]
for group in itertools.groupby(iter(xx), lambda x: yy[x]):
    print group[0], list(group[1])

생산물:

0 [0, 1, 2]
1 [3, 4, 5]
0 [6, 7, 8, 9]

경고:

list(groupby(...)) 구문은 의도한 대로 작동하지 않습니다.내부 반복자 객체를 파괴하는 것 같으므로 다음을 사용하십시오.

for x in list(groupby(range(10))):
    print(list(x[1]))

생산할 것입니다:

[]
[]
[]
[]
[]
[]
[]
[]
[]
[9]

대신 list(groupby(...)) 대신 [(k, list(g)) for k,g in groupby(...)]를 시도하거나 해당 구문을 자주 사용하는 경우

def groupbylist(*args, **kwargs):
    return [(k, list(g)) for k, g in groupby(*args, **kwargs)]

성가신(작은 데이터의 경우) 반복자를 모두 피하면서 그룹별 기능에 액세스할 수 있습니다.

정렬 없이 groupby가 작동하지 않는 또 다른 예를 제시하고 싶습니다.James Sulak의 예에서 채택됨

from itertools import groupby

things = [("vehicle", "bear"), ("animal", "duck"), ("animal", "cactus"), ("vehicle", "speed boat"), ("vehicle", "school bus")]

for key, group in groupby(things, lambda x: x[0]):
    for thing in group:
        print "A %s is a %s." % (thing[1], key)
    print " "

출력은

A bear is a vehicle.

A duck is a animal.
A cactus is a animal.

A speed boat is a vehicle.
A school bus is a vehicle.

차량이 있는 두 그룹이 있는 반면, 하나의 그룹만 기대할 수 있습니다.

@CaptSolo, 귀하의 예를 시도했지만 작동하지 않았습니다.

from itertools import groupby 
[(c,len(list(cs))) for c,cs in groupby('Pedro Manoel')]

산출:

[('P', 1), ('e', 1), ('d', 1), ('r', 1), ('o', 1), (' ', 1), ('M', 1), ('a', 1), ('n', 1), ('o', 1), ('e', 1), ('l', 1)]

보시다시피 두 개의 o와 두 개의 e가 있지만 서로 다른 그룹으로 나뉘어져 있습니다.그때 나는 groupby 함수에 전달된 목록을 정렬해야 한다는 것을 깨달았습니다.따라서 올바른 사용법은 다음과 같습니다.

name = list('Pedro Manoel')
name.sort()
[(c,len(list(cs))) for c,cs in groupby(name)]

산출:

[(' ', 1), ('M', 1), ('P', 1), ('a', 1), ('d', 1), ('e', 2), ('l', 1), ('n', 1), ('o', 2), ('r', 1)]

목록이 정렬되지 않은 경우 groupby 함수를 기억하세요. 작동 안 할 것이다!

Python의 itertools.groupby()를 어떻게 사용합니까?

groupby를 사용하여 반복할 항목을 그룹화할 수 있습니다.groupby에 반복 가능 및 선택 사항을 제공합니다. 열쇠 iterable에서 나오는 항목을 확인하는 함수/콜러블이며, 키 콜러블의 결과와 다른 iterable의 실제 항목의 2튜플을 제공하는 반복자를 반환합니다.도움말에서:

groupby(iterable[, keyfunc]) -> create an iterator which returns
(key, sub-iterator) grouped by each value of key(value).

다음은 개수별로 그룹화하기 위해 코루틴을 사용하는 groupby의 예입니다. 호출 가능한 키를 사용합니다(이 경우 coroutine.send) 얼마나 많은 반복 횟수와 요소의 그룹화된 하위 반복기에 대한 수를 뱉어냅니다.

import itertools


def grouper(iterable, n):
    def coroutine(n):
        yield # queue up coroutine
        for i in itertools.count():
            for j in range(n):
                yield i
    groups = coroutine(n)
    next(groups) # queue up coroutine

    for c, objs in itertools.groupby(iterable, groups.send):
        yield c, list(objs)
    # or instead of materializing a list of objs, just:
    # return itertools.groupby(iterable, groups.send)

list(grouper(range(10), 3))

인쇄물

[(0, [0, 1, 2]), (1, [3, 4, 5]), (2, [6, 7, 8]), (3, [9])]

정렬 및 그룹화

from itertools import groupby

val = [{'name': 'satyajit', 'address': 'btm', 'pin': 560076}, 
       {'name': 'Mukul', 'address': 'Silk board', 'pin': 560078},
       {'name': 'Preetam', 'address': 'btm', 'pin': 560076}]


for pin, list_data in groupby(sorted(val, key=lambda k: k['pin']),lambda x: x['pin']):
...     print pin
...     for rec in list_data:
...             print rec
... 
o/p:

560076
{'name': 'satyajit', 'pin': 560076, 'address': 'btm'}
{'name': 'Preetam', 'pin': 560076, 'address': 'btm'}
560078
{'name': 'Mukul', 'pin': 560078, 'address': 'Silk board'}

제가 본 한 가지 유용한 예가 도움이 될 수 있습니다.

from itertools import groupby

#user input

myinput = input()

#creating empty list to store output

myoutput = []

for k,g in groupby(myinput):

    myoutput.append((len(list(g)),int(k)))

print(*myoutput)

샘플 입력:14445221

샘플 출력:(1,1) (3,4) (1,5) (2,2) (1,1)

자신만의 groupby 함수를 작성할 수 있습니다.

           def groupby(data):
                kv = {}
                for k,v in data:
                    if k not in kv:
                         kv[k]=[v]
                    else:
                        kv[k].append(v)
           return kv

     Run on ipython:
       In [10]: data = [('a', 1), ('b',2),('a',2)]

        In [11]: groupby(data)
        Out[11]: {'a': [1, 2], 'b': [2]}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top