Как сказать различие между итератором и повторяемым?

Убедитесь, что на панели предварительного просмотра установлен флажок «Показать макеты».

Show Layout decorations

14
задан nikow 27 April 2009 в 16:24
поделиться

4 ответа

'iterator' if obj is iter(obj) else 'iterable'
12
ответ дан 1 December 2019 в 13:48
поделиться

Из-за утиного ввода Python,

Любой объект повторяем, если он определяет next() и __iter__() метод возвращает себя.

Если сам объект не имеет next() метод, __iter__() может возвратить любой объект, который имеет a next() метод

Вы могли отослать этот вопрос видеть Iterability в Python

0
ответ дан 1 December 2019 в 13:48
поделиться
import itertools

def process(iterable):
    work_iter, backup_iter= itertools.tee(iterable)

    for item in work_iter:
        # bla bla
        if need_to_startover():
            for another_item in backup_iter:

Та проклятая машина времени, которую Raymond одолжил от Guido …

2
ответ дан 1 December 2019 в 13:48
поделиться

Однако существует важное семантическое различие между двумя...

Едва ли семантический или важный. Они оба повторяемы - они оба работа с для оператора.

Различие, например, важно, когда каждый хочет циклично выполниться многократно.

Когда это когда-либо подходит? Необходимо будет быть более конкретными. В редких случаях, когда необходимо сделать два, проходит через повторяемый набор, часто существуют лучшие алгоритмы.

Например, скажем, Вы обрабатываете список. Можно выполнить итерации через список всего, что Вы хотите. Почему Вы попадали в историю с итератором вместо повторяемого? Хорошо это не работало.

Хорошо, вот тот. Вы читаете файл в двух передачах, и необходимо знать, как сбросить повторяемое. В этом случае это - файл, и seek требуется; или завершение и вновь открывание. Это чувствует себя неприглядным. Вы можете readlines получить список, который позволяет две передачи без сложности. Таким образом, это не необходимо.

Ожидайте, что, если у нас есть файл, настолько большой, мы не можем считать все это в память? И по неясным причинам мы не можем искать, также. Что затем?

Теперь, мы до основных элементов двух передач. На первичной обработке мы накопили что-то. Индекс или сводка или что-то. Индекс имеет данные всего файла. Сводка, часто, является реструктуризацией данных. С небольшим изменением из "сводки" для "реструктурирования" мы сохранили данные файла в новой структуре. В обоих случаях нам не нужен файл - мы можем использовать индекс или сводку.

Все алгоритмы "с двумя передачами" могут быть изменены на одну передачу исходного итератора или повторяемые и вторую передачу другой структуры данных.

Это ни один LYBL или EAFP. Это - дизайн алгоритма. Вы не должны сбрасывать итератор - YAGNI.


Править

Вот пример проблемы итератора / повторяемой проблемы. Это - просто плохо разработанный алгоритм.

it = iter(xrange(3))
for i in it: print i,; #prints 1,2,3 
for i in it: print i,; #prints nothing

Это тривиально фиксируется.

it = range(3)
for i in it: print i
for i in it: print i

"Многократно параллельно" тривиально фиксируется. Запишите API, который требует повторяемого. И когда кто-то отказывается читать документацию API или отказывается следовать за нею считав ее, их повреждения материала. Как это должно.

"Хороший охранять против случая был пользователь, обеспечивает только итератор, когда несколько передач необходимы", оба примеры безумных людей написание кода, которое повреждает наш простой API.

Если кто-то достаточно безумен, чтобы считать большинство (но не весь документ API) и обеспечить итератор, когда повторяемое требовалось, необходимо найти этого человека и преподавать их (1) как прочитать всю документацию API и (2) следуете документации API.

Проблема "гарантии" не очень реалистична. Эти сумасшедшие программисты удивительно редки. И в нескольких случаях, когда это действительно возникает, Вы знаете, кто они и могут помочь им.


Редактирование 2

"Мы должны читать, та же структура многократно" алгоритмы являются фундаментальной проблемой.

Не делайте этого.

for element in someBigIterable:
    function1( element )
for element in someBigIterable:
    function2( element )
...

Сделайте это, вместо этого.

for element in someBigIterable:
    function1( element )
    function2( element )
    ...

Или, рассмотрите что-то вроде этого.

for element in someBigIterable:
    for f in ( function1, function2, function3, ... ):
        f( element )

В большинстве случаев этот вид "центра" Ваших алгоритмов приводит к программе, которую могло бы быть легче оптимизировать и могла бы быть сетевым улучшением производительности.

3
ответ дан 1 December 2019 в 13:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: