Получение числа элементов в итераторе в Python

использовать find_elements_by_xpath и взять счетчик длины.

totalcount= len(driver.find_elements_by_xpath("//div[@class='panel-content']/div[@class='row ehi-pd']"))
print(totalcount)
117
задан Tomasz Wysocki 24 August 2011 в 13:52
поделиться

9 ответов

Нет. Это невозможно.

Пример:

import random

def gen(n):
    for i in xrange(n):
        if random.randint(0, 1) == 0:
            yield i

iterator = gen(10)

Длина итератора неизвестна, пока вы не выполните итерацию по нему.

92
ответ дан 24 November 2019 в 02:00
поделиться

По-видимому, Вы хотите, считают количество объектов, не выполняя итерации через, так, чтобы итератор не был исчерпан, и Вы используете его снова позже. Это возможно с copy или deepcopy

import copy

def get_iter_len(iterator):
    return sum(1 for _ in copy.copy(iterator))

###############################################

iterator = range(0, 10)
print(get_iter_len(iterator))

if len(tuple(iterator)) > 1:
    print("Finding the length did not exhaust the iterator!")
else:
    print("oh no! it's all gone")

, вывод" Finding the length did not exhaust the iterator!"

Дополнительно (и необдуманно), Вы можете тень встроенное len функция следующим образом:

import copy

def len(obj, *, len=len):
    try:
        if hasattr(obj, "__len__"):
            r = len(obj)
        elif hasattr(obj, "__next__"):
            r = sum(1 for _ in copy.copy(obj))
        else:
            r = len(obj)
    finally:
        pass
    return r
-1
ответ дан 24 November 2019 в 02:00
поделиться

Есть два способа узнать длину «чего-то» на компьютере.

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

Другой способ - перебрать его и посчитать, насколько он велик.

3
ответ дан 24 November 2019 в 02:00
поделиться

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

9
ответ дан 24 November 2019 в 02:00
поделиться

Обычно такой тип информации помещают в заголовок файла, и pysam предоставляет вам к нему доступ. Я не знаю формата, но проверяли ли вы API?

Как говорили другие, вы не можете узнать длину из итератора.

0
ответ дан 24 November 2019 в 02:00
поделиться

Вроде. Вы можете проверить метод __ length_hint __ , но имейте в виду, что (по крайней мере, до Python 3.4, как услужливо указывает gsnedders) это недокументированная деталь реализации ( после сообщения в ветке ), которые могут вместо этого исчезнуть или вызвать носовых демонов.

В противном случае - нет. Итераторы - это просто объект, который предоставляет только метод next () . Вы можете коллировать столько раз, сколько потребуется, и они могут или не могут в конечном итоге сделать рейз StopIteration . К счастью, такое поведение в большинстве случаев прозрачно для кодировщика. :)

17
ответ дан 24 November 2019 в 02:00
поделиться

Нет, любой метод потребует от вас разрешения всех результатов. Вы можете сделать

iter_length = len(list(iterable))

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

Если вы сообщите нам, какую реальную проблему вы пытаетесь решить, это поможет нам найти лучший способ достичь вашей цели.

Изменить: использование list () приведет к одновременному считыванию итерации в память целиком, что может быть нежелательно. Другой способ - сделать

sum(1 for _ in iterable)

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

62
ответ дан 24 November 2019 в 02:00
поделиться

Этот код должен работать:

>>> iter = (i for i in range(50))
>>> sum(1 for _ in iter)
50

Хотя он выполняет итерацию по каждому элементу и считает их, это самый быстрый способ сделать это.

Это также работает, когда итератор не имеет элемента:

>>> sum(1 for _ in range(0))
0

Конечно, он работает вечно для бесконечного ввода, поэтому помните, что итераторы могут быть бесконечными:

>>> sum(1 for _ in itertools.count())
[nothing happens, forever]

Также имейте в виду, что итератор будет быть исчерпанным , и дальнейшие попытки его использования не обнаружат никаких элементов . Это неизбежное следствие конструкции итератора Python. Если вы хотите сохранить элементы, вам придется хранить их в списке или что-то в этом роде.

197
ответ дан 24 November 2019 в 02:00
поделиться

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

Учитывая, что ваш вопрос мотивирован применением библиотеки pysam, я могу дать более конкретный ответ: я участвую в PySAM, и окончательный ответ заключается в том, что файлы SAM / BAM не обеспечивают точное количество выровненных читает. Эту информацию также нелегко получить из индексного файла BAM. Лучшее, что можно сделать, - это оценить приблизительное количество выравниваний, используя местоположение указателя файла после чтения ряда выравниваний и экстраполяции на основе общего размера файла. Этого достаточно, чтобы реализовать индикатор выполнения, но не метод подсчета выравниваний за постоянное время.

8
ответ дан 24 November 2019 в 02:00
поделиться
Другие вопросы по тегам:

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