Python, определяющий итераторы для словарного понимания для класса - PullRequest
0 голосов
/ 28 октября 2018

Я хочу уточнить у кого-нибудь, правильно ли я определил функцию итерации.Для объяснения, пожалуйста, рассмотрите следующий пример:

x=[{'n':'foo', 'a': [1,2,3], 'b':[2,3,5]}, {'n':'baz','a':[4,5,6], 'b':[7,8,9]},
   {'n':'foo', 'a': [4,3,4], 'b':[1,5,6]}, {'n':'bar','a':[1,2,2], 'b':[2,5,6]}]

quick_dict = {key['n']: [sample['a'] for sample in x if sample['n']==key['n']] for key in x}

Это работает, как и ожидалось, и выводит:

{'foo': [[1, 2, 3], [4, 3, 4]], 'baz': [[4, 5, 6]], 'bar': [[1, 2, 2]]}

Я пытаюсь сделать что-то подобное для класса, который я определил, используя __next__ и __iter__ методы.Экземпляр класса имеет много функций и атрибутов, но для целей этого вопроса важен только атрибут samples, поскольку он представляет собой список словарей, точно такой же, как в приведенном выше примере.Я определил методы следующим образом:

def __next__(self):
    if self.itercounter < len(self.samples)-1:
        self.itercounter +=1
        return self.samples[self.itercounter]
    else:
        raise StopIteration

def __iter__(self):
    self.itercounter = -1
    return self

Кажется, это работает для списочных представлений, но не для словарных пониманий.

Если я сделаю:

quick_dict = {key['Name']: [sample['CM'] for sample in data if sample['Name'] == key['Name']]
              for key in data.samples}

, то это сработает, потому что он напрямую обращается к списку словарей и знает, что делать.С другой стороны, если я делаю

quick_dict = {key['Name']: [sample['CM'] for sample in data if sample['Name'] == key['Name']]
              for key in data}

, тогда он выполняет мои функции и не работает.Он просто возвращает словарь с одним ключом.Здесь 'CM' - это просто ключ, подобный 'a' в примере.

Что я делаю неправильно в своем определении __iter__ и __next__?

1 Ответ

0 голосов
/ 28 октября 2018

Ваше второе определение quick_dict перебирает data с for sample in data, а уже перебирает его с for key in data.Однако ваша реализация __iter__ и __next__ использует один атрибут экземпляра для управления итерацией, а это означает, что вложенная итерация с data не будет работать, поскольку второй (вложенный) вызов __iter__ сбрасывает счетчик.Чтобы поддержать вложенную итерацию, исключите __next__ и попросите __iter__ вернуть генератор вместо:

def __iter__(self):
    i = -1
    while i < len(self.samples)-1:
        i += 1
        yield self.samples[i]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...