Нет ничего специального об Уникальных индексах - они следуют за теми же опциями случая как другие индексы.
Конечно, это то, что вы хотите:
import itertools
import operator
def main():
for let, gen in itertools.groupby(big_gen(), key=operator.itemgetter(0)):
secgen = itertools.imap(operator.itemgetter(1), gen)
printer(let, secgen)
groupby
выполняет здесь основную работу - ключ =
просто указывает, какое поле сгруппировать по.
Результирующий генератор должен быть заключен в imap
только потому, что вы указали подпись принтера
, которая будет использовать итератор по номеру, тогда как по своей природе groupby
возвращает итераторы по тем же элементам, которые он получает в качестве входных данных - здесь кортежи из двух элементов, за которыми следует буква, за которой следует число - но это не совсем то, что имеет отношение к заголовку вашего вопроса.
Ответ на этот заголовок гласит, что, да, функция Python может отлично выполнять ту работу, которую вы хотите - itertools.groupby
фактически делает именно это. Я рекомендую внимательно изучить модуль itertools , он »
У вас здесь небольшая проблема. Вы хотите, чтобы функция printer () использовала генератор для каждой группы, но на самом деле у вас есть один и тот же генератор, генерирующий все группы. На мой взгляд, у вас есть два варианта:
1) Изменить big_gen () на генераторы:
import random
def big_gen():
i = 0
group = 'a'
while group != 'd':
def gen():
i += 1
yield i
if random.random() < 0.20:
group = chr(ord(group) + 1)
yield group, gen
from itertools import imap
imap(lambda a: printer(*a), big_gen())
2) Изменить printer (), чтобы сохранить состояние и замечать, когда группа изменяется (сохраняя исходную функцию big_gen ()) :
def printer(generator):
group = None
for grp, num in generator:
if grp != group:
print "These numbers are in group %s:" % grp
group = grp
print "\t%s" % num