(iterable, key=None)
| 1615 | # Begin groupby() recipe ####################################### |
| 1616 | |
| 1617 | def groupby(iterable, key=None): |
| 1618 | # [k for k, g in groupby('AAAABBBCCDAABBB')] → A B C D A B |
| 1619 | # [list(g) for k, g in groupby('AAAABBBCCD')] → AAAA BBB CC D |
| 1620 | |
| 1621 | keyfunc = (lambda x: x) if key is None else key |
| 1622 | iterator = iter(iterable) |
| 1623 | exhausted = False |
| 1624 | |
| 1625 | def _grouper(target_key): |
| 1626 | nonlocal curr_value, curr_key, exhausted |
| 1627 | yield curr_value |
| 1628 | for curr_value in iterator: |
| 1629 | curr_key = keyfunc(curr_value) |
| 1630 | if curr_key != target_key: |
| 1631 | return |
| 1632 | yield curr_value |
| 1633 | exhausted = True |
| 1634 | |
| 1635 | try: |
| 1636 | curr_value = next(iterator) |
| 1637 | except StopIteration: |
| 1638 | return |
| 1639 | curr_key = keyfunc(curr_value) |
| 1640 | |
| 1641 | while not exhausted: |
| 1642 | target_key = curr_key |
| 1643 | curr_group = _grouper(target_key) |
| 1644 | yield curr_key, curr_group |
| 1645 | if curr_key == target_key: |
| 1646 | for _ in curr_group: |
| 1647 | pass |
| 1648 | |
| 1649 | # End groupby() recipe ######################################### |
| 1650 |
no test coverage detected