How do I get at the contents of an iterator?
beautifulsoup, python
Solution
I try to work out a more general answer:
An iterable is an object which can be iterated over. These include lists, tuples, etc. On request, they give an iterator.
An iterator is an object which is used for iteration. It gives a value on each request, and if it is over, it is over. These are generators, list iterators etc., but also e. g. file objects. Every iterator is iterable and gives itself as its iterator.
Example:
a = []
b = iter(a)
print a, b # -> [] <listiterator object at ...>
If you do
for i in a: ...
a is asked for an iterator via its `__iter__()` method and this iterator is then queried for the next elements until exhausted. This happens via the `.next()` (resp. `__next__()` in 3.x) method.
Indexing is a completely different thing. As iteration can happen via indexing if the object doesn't have an `.__iter__()` method, every indexable object is iterable, but not vice versa.
Problem
I'm thoroughly puzzled. I have a block of HTML that I scraped out of a larger table. It looks about like this: ``` <td align="left" class="page">Number:\xc2\xa0<a class="topmenu" href="http://www.example.com/whatever.asp?search=724461">724461</a> Date:\xc2\xa01/1/1999 Amount:\xc2\xa0$2.50 <br/>Person:<br/><a class="topmenu" href="http://www.example.com/whatever.asp?search=LAST&searchfn=FIRST">LAST,\xc2\xa0FIRST </a> </td> ``` (Actually, it looked worse, but I regexed out a lot of line breaks) I need to get the lines out, and break up the Date/Amount line. It seemed like the place to start was to find the children of that block of HTML. The block is a string because that's how regex gave it back to me. So I did: ``` text_soup = BeautifulSoup(text) text_children = text_soup.find('td').childGenerator() ``` I've worked out that I can only iterate through `text_children` once, though I don't understand why that is. It's a `listiterator` type, which I'm struggling to understand. I'm used to being able to assume that if I can iterate through something with a for loop I can call on any one element with something like text_children[0]. That doesn't seem to be the case with an iterator. If I create a list with: ``` my_array = ["one","two","three"] ``` I can use `my_array[1]` to see the second item in the array. If I try to do `text_children[1]` I get an error: ``` TypeError: 'listiterator' object is not subscriptable ``` How do I get at the contents of an iterator?