2

Following code block works and it seems pretty legit to me. There is TP two times in TP Tutorials Point TP string so the number of matches should be 2. Also the iteration over this list should work.

s = 'TP Tutorials Point TP'

out = re.findall(r'TP', s)

assert len(list(out)) == 2

# this loop will print 2 times matched string
for m in out:
    print(m)

But what is going on here?

s = 'TP Tutorials Point TP'

out = re.finditer(r'TP', s)

# seems OK so far
assert len(list(out)) == 2

# !!! no output here !!!
for m in out:
    print(m)

Why I'm unable to iterate over returned output of finditer method? In following post it is shown that finditer should also work. My python version: 3.8.10

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Wakan Tanka
  • 7,542
  • 16
  • 69
  • 122

2 Answers2

5

re.finditer, as the name implies, returns an iterator. When you use len(list(out)) you consume the iterator, and from then on it is empty.

You can test it like so:

assert len(list(out)) == 2 # First will work
assert len(list(out)) == 2 # Second won't

Just remove the assert line and you'll receive output:

out = re.finditer(r'TP', s)

# We love output :D
for m in out:
    print(m)

For more info, you can consult this question.

Bharel
  • 23,672
  • 5
  • 40
  • 80
1

Your issue is with this line:

assert len(list(out)) == 2

Once you execute list(out) you exhaust the iterator and then when you try to iterate it again there is nothing left. If you remove that line from your code it works fine:

s = 'TP Tutorials Point TP'

out = re.finditer(r'TP', s)

# lots of output!
for m in out:
    print(m)

Output:

<re.Match object; span=(0, 2), match='TP'>
<re.Match object; span=(19, 21), match='TP'>
Nick
  • 138,499
  • 22
  • 57
  • 95