Python — вызываемый размер итератора?

Я просматриваю некоторый текстовый файл для определенной строки с методом.

re.finditer(pattern,text) Я хотел бы знать, когда это ничего не возвращает. подразумевать, что это ничего не могло найти в переданном тексте.

Я знаю, что вызываемые итераторы, иметь next() и __iter__

Я хотел бы знать, мог ли я получить размер или узнать, не возвращает ли он сопоставления строк мой шаблон.

11
задан myusuf3 24 February 2013 в 01:00
поделиться

4 ответа

РЕДАКТИРОВАТЬ 3: Ответ @hynekcer намного лучше этого.

РЕДАКТИРОВАТЬ 2: Это не сработает, если у вас бесконечный итератор или тот, который потребляет слишком много гигабайт (в 2010 году 1 гигабайт все еще является большим объемом оперативной памяти / дискового пространства) RAM / дискового пространства.

Вы уже видели хороший ответ, но вот дорогостоящий прием, который вы можете использовать, если хотите съесть торт и тоже его :) Хитрость в том, что мы должны клонировать торт, и когда вы закончите поедая, кладем обратно в ту же коробку. Помните, когда вы перебираете итератор, он обычно становится пустым или, по крайней мере, теряет ранее возвращенные значения.

>>> def getIterLength(iterator):
    temp = list(iterator)
    result = len(temp)
    iterator = iter(temp)
    return result

>>>
>>> f = xrange(20)
>>> f
xrange(20)
>>> 
>>> x = getIterLength(f)
>>> x
20
>>> f
xrange(20)
>>> 

РЕДАКТИРОВАТЬ: Вот более безопасная версия, но ее использование все же требует некоторой дисциплины. Это не совсем похоже на Pythonic. Вы получите лучшее решение, если разместите весь соответствующий пример кода, который пытаетесь реализовать.

>>> def getIterLenAndIter(iterator):
    temp = list(iterator)
    return len(temp), iter(temp)

>>> f = iter([1,2,3,7,8,9])
>>> f
<listiterator object at 0x02782890>
>>> l, f = getIterLenAndIter(f)
>>> 
>>> l
6
>>> f
<listiterator object at 0x02782610>
>>> 
7
ответ дан 3 December 2019 в 02:40
поделиться

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

5
ответ дан 3 December 2019 в 02:40
поделиться

Вы можете получить количество элементов в итераторе, выполнив:

len( [m for m in re.finditer(pattern, text) ] )

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

count = 0
for item in re.finditer(pattern, text):
    count += 1

Сложный подход к циклу for - использовать сокращение для эффективного подсчета элементов в итераторе один за другим. По сути, это то же самое, что и цикл for:

reduce( (lambda x, y : x + 1), myiterator, 0)

Он в основном игнорирует y , переданный в reduce, и просто добавляет единицу. Он инициализирует текущую сумму равной 0 .

1
ответ дан 3 December 2019 в 02:40
поделиться

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

matches = list(re.finditer(pattern,text))
if matches:
  do_something()
print("Found",len(matches),"matches")
0
ответ дан 3 December 2019 в 02:40
поделиться
Другие вопросы по тегам:

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