python2 - zip_longest




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

파이썬의 itertools.groupby() 함수를 실제로 사용하는 방법에 대한 이해하기 쉬운 설명을 찾을 수 없었습니다. 내가하려는 것은 이것입니다 :

  • 목록을 가져 lxml 이 경우 객체화 된 lxml 요소의 하위 항목입니다.
  • 몇 가지 기준에 따라 그룹으로 나눕니다.
  • 그런 다음 나중에 각 그룹을 개별적으로 반복하십시오.

설명서예제를 검토했지만 간단한 숫자 목록을 넘어서 적용하는 데 문제가있었습니다.

어떻게 itertools.groupby() 합니까? 사용해야하는 다른 기술이 있습니까? 좋은 "전제 조건"독서에 대한 포인터도 감사하겠습니다.


정렬 및 그룹화

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

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

groupby를 사용하여 반복 할 항목을 그룹화 할 수 있습니다. iterable과 iterable에서 나오는 항목을 확인할 수있는 선택적 함수 / 호출 가능을 그룹별로 제공하고, 호출 가능한 키 결과와 실제 항목의 결과의 두 튜플을 제공하는 반복자를 반환합니다. 또 다른 iterable. 도움에서 :

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

다음은 코 루틴을 사용하여 카운트로 그룹화하는 예입니다. 키 호출 가능 (이 경우 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])]

groupby를 사용하는 깔끔한 요령은 한 줄에 길이 인코딩을 실행하는 것입니다.

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

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

편집 : 이것은 itertools.groupby 를 SQL GROUP BY 의미와 분리하는 것입니다. itertools는 반복자를 미리 정렬하지 않으며 (일반적으로 정렬 할 수 없으므로) 동일한 "키"를 가진 그룹은 병합되지 않습니다.


경고:

구문 목록 (groupby (...))이 원하는 방식으로 작동하지 않습니다. 내부 반복자 객체를 파괴하는 것 같습니다.

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

생산할 것이다 :

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

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

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

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


또 다른 예:

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)

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

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]

자체 그룹 별 기능을 작성할 수 있습니다.

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

코드를 보여줄 수 있습니까?

파이썬 문서의 예는 매우 간단합니다.

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 메소드는 실제로 목록을 반복하며 키가 변경 될 때마다 새 그룹을 만듭니다.


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

docs 에서 우리는 그것이 무엇을 할 수 있는지 더 많이 모 읍니다.

# [k for k, g in groupby('AAAABBBCCDAABBB')] --> ABCDAB

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

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

풍모

  • A. 연속 항목을 그룹화
  • B. iterable에 따라 항목의 모든 항목을 그룹화
  • C. 키 기능으로 항목을 그룹화하는 방법 지정 *

비교

# Define a printer for comparing outputs
>>> def print_groupby(iterable, keyfunc=None):
...    for k, g in it.groupby(iterable, keyfunc):
...        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
>>> # keyfunc = lambda s: s.islower()                      # equivalent
>>> def keyfunc(s):
...     """Return a True if a string is lowercase, else False."""   
...     return s.islower()
>>> print_groupby(sorted("bCAaCacAADBbB"), keyfunc)
key: 'False'--> group: ['A', 'A', 'A', 'B', 'B', 'C', 'C', 'D']
key: 'True'--> group: ['a', 'a', 'b', 'b', 'c']

용도

참고 : 후자의 예제 중 일부는 Víctor Terrón의 PyCon (talk) (Spanish) , "Itertools와 함께 새벽에 쿵푸"에서 파생되었습니다. C로 작성된 그룹 별 소스 코드 도 참조하십시오.

* 모든 항목을 통과하고 비교하여 결과에 영향을주는 기능입니다. 주요 기능을 가진 다른 객체로는 sorted() , max()min() 있습니다.

응답

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






iteration