Использование itertools.tee для дублирования вложенного итератора (т.е. itertools.groupby) - PullRequest
0 голосов
/ 01 января 2019

Я читаю файл (хотя и выполняю дорогостоящую логику), который мне нужно будет повторять несколько раз в разных функциях, поэтому я действительно хочу прочитать и проанализировать файл только один раз.

Функция синтаксического анализаанализирует файл и возвращает itertools.groupby объект.

def parse_file():
    ...
    return itertools.groupby(lines, key=keyfunc)

Я думал о том, чтобы сделать следующее:

csv_file_content = read_csv_file()

file_content_1, file_content_2 = itertools.tee(csv_file_content, 2)

foo(file_content_1)
bar(file_content_2)

Однако, itertools.tee, похоже, может только "дублировать"внешний итератор, в то время как внутренний (вложенный) итератор все еще ссылается на оригинал (следовательно, он будет исчерпан после итерации итератора 1 st , возвращенного itertools.tee).

Автономный MCVE:

from itertools import groupby, tee

li = [{'name': 'a', 'id': 1},
      {'name': 'a', 'id': 2},
      {'name': 'b', 'id': 3},
      {'name': 'b', 'id': 4},
      {'name': 'c', 'id': 5},
      {'name': 'c', 'id': 6}]

groupby_obj = groupby(li, key=lambda x:x['name'])
tee_obj1, tee_obj2 = tee(groupby_obj, 2)

print(id(tee_obj1))
for group, data in tee_obj1:
    print(group)
    print(id(data))
    for i in data:
        print(i)

print('----')

print(id(tee_obj2))
for group, data in tee_obj2:
    print(group)
    print(id(data))
    for i in data:
        print(i)

Выходы

2380054450440
a
2380053623136
{'name': 'a', 'id': 1}
{'name': 'a', 'id': 2}
b
2380030915976
{'name': 'b', 'id': 3}
{'name': 'b', 'id': 4}
c
2380054184344
{'name': 'c', 'id': 5}
{'name': 'c', 'id': 6}
----
2380064387336
a
2380053623136  # same ID as above
b
2380030915976  # same ID as above 
c
2380054184344  # same ID as above

Как эффективно дублировать вложенный итератор?

1 Ответ

0 голосов
/ 01 января 2019

Кажется, что grouped_object (class 'itertools.groupby ') будет потребляться один раз, даже в itertools.tee.Также не работает параллельное назначение одного и того же grouped_object:

tee_obj1, tee_obj2 = groupby_obj, groupby_obj

Работает глубокая копия из grouped_object:

tee_obj1, tee_obj2 = copy.deepcopy(groupby_obj), groupby_obj
...