Python: Можно ли заранее узнать, сколько итераций в объекте итератора? - PullRequest
4 голосов
/ 27 декабря 2011

До сих пор, если бы я хотел узнать, сколько итераций в итераторе (в моем случае это количество белковых последовательностей в файле), я сделал:

count = 0
for stuff in iterator:
    count += 1
print count

Однако я хочу разделить итератор пополам, поэтому мне нужно знать общее количество итераций. Есть ли способ узнать количество итераций, которые будут выполняться без повторения итератора?

Ответы [ 5 ]

10 голосов
/ 27 декабря 2011

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

Если вы можете обеспечить конечность итератора, один из способов сделать то, что вы просите, - преобразовать его в список (используя list(iterator)), а затем использовать обычные функции списка (len, срез), чтобы разделить его половина. Конечно, таким образом все элементы будут в памяти одновременно, что может или не может быть приемлемо в вашем случае.

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

5 голосов
/ 27 декабря 2011

Поскольку протокол итератора определяет только два метода:

iterator.__iter__()

iterator.next()

ответ - нет, в общем случае вы не можете знать количество элементов в конечном итераторе, не просматривая их.

1 голос
/ 27 декабря 2011

Я думаю, что проблема, поднятая Ником де Кляйном, связана с «проблемой остановки» (http://en.wikipedia.org/wiki/Halting_problem). Так что не может быть никакого метода, чтобы определить, как долго итератор по веским теоретическим причинам!

Я имею в виду, что я мог бы написать итератор Python таким образом, чтобы, если такая функция-член существует, я решил проблему остановки.

Конечно, конкретный контейнер или ваш собственный класс (как предложено Паоло) может иметь такой метод. Но не может быть общего, работающего за конечное время!

1 голос
/ 27 декабря 2011

вы можете использовать list() для преобразования вашего итератора в список, а len() для получения размера списка, например:

len(list(iterator))
0 голосов
/ 27 декабря 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...