我很困惑。我有一个HTML块,我从一个更大的表中删除。它看起来像这样:
<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>
(实际上,它看起来更糟糕,但我重复了很多换行符)
我需要排除这些线,并打破日期/金额线。似乎开始的地方是找到那块HTML的孩子。该块是一个字符串,因为这是正则表达式给我的回报。所以我做了:
text_soup = BeautifulSoup(text)
text_children = text_soup.find('td').childGenerator()
我已经解决了I can only iterate through text_children
once,虽然我不明白为什么会这样。它是listiterator
类型,我很难理解。
我习惯于假设如果我可以使用for循环迭代某些东西,我可以使用text_children [0]之类的东西调用任何一个元素。迭代器似乎不是这种情况。如果我创建一个列表:
my_array = ["one","two","three"]
我可以使用my_array[1]
查看数组中的第二项。如果我尝试text_children[1]
我收到错误:
TypeError: 'listiterator' object is not subscriptable
如何获取迭代器的内容?
答案 0 :(得分:8)
您可以通过以下方法轻松地从迭代器构造列表:
my_list = list(your_generator)
现在您可以下标元素:
print(my_list[1])
获取价值的另一种方法是使用next
。这将从迭代器中提取下一个值,但正如您已经发现的那样,一旦从迭代器中提取一个值,就不能总是将其重新放入(无论是否可以将其重新放入,完全取决于正在迭代的对象及其next
方法的实际外观。)
这样做的原因是,您通常只需要一个可以迭代的对象。迭代器很好,因为它们一次计算元素1而不是需要存储所有值。换句话说,迭代器中只有一个元素一次消耗系统内存 - 而不是列表或元组,其中所有元素通常在开始迭代之前存储在内存中。
答案 1 :(得分:2)
我试着找出一个更一般的答案:
iterable是一个可以迭代的对象。这些包括列表,元组等。根据要求,它们提供迭代器。
迭代器是使用进行迭代的对象。它为每个请求提供一个值,如果它结束,它就结束了。这些是生成器,列表迭代器等,但也是e。 G。文件对象。每个迭代器都是可迭代的,并将自己作为迭代器。
示例:
a = []
b = iter(a)
print a, b # -> [] <listiterator object at ...>
如果你这样做
for i in a: ...
a通过其__iter__()
方法请求迭代器,然后查询此迭代器以查找下一个元素,直到用完为止。这是通过.next()
(在3.x中的resp。__next__()
)方法发生的。
索引是完全不同的事情。如果对象没有.__iter__()
方法,则可以通过索引进行迭代,因此每个可索引对象都是可迭代的,但反之亦然。
答案 2 :(得分:1)
list(generator)
答案很长,并解释原因:
当你创建一个生成器时,或者在你的情况下是一个'listiterator',它是一个美丽的汤使用的生成器,你实际上并没有创建一个项目列表。你正在创建一个对象(生成器),它知道如何迭代一定数量的项目,一次一个,(next()
)
而不是你想要的东西,比如一本带有页面的书。
你得到一台打字机。打字机可以创建带有页面的书籍,但一次只能创建一页。现在,如果你刚刚开始,一次看一个就像一个for循环,那么是的,它几乎就像读一本普通的书。
但与普通书籍不同,一旦打字机完成了一个页面,你就无法倒退,那个页面现在已经消失了。
我希望这是有道理的。