首页 > 解决方案 > 在另一个列表理解中过滤列表理解

问题描述

这是我当前的代码:

[[td.text.strip() for td in tr.find_all('td')] for tr in table.find_all('tr')]

本质上,我正在做的是解析从网页获取的 BeautifulSoup + Requests 表的输出。不管目的是什么,这部分[td.text.strip() for td in tr.find_all('td')]都给了我一个代表一行的列表,它工作正常。不过,我想要的是过滤这个列表,删除第一个元素是空字符串的行。所以,我的代码会变成

[[td.text.strip() for td in tr.find_all('td')] for tr in table.find_all('tr') if [td.text.strip() for td in tr.find_all('td')][0] != ""

这是可悲和可怕的。我来自 Scala 中的函数式编程背景,因此使用 map、filter 和 reduce 操作对我来说很好,但是在 Python 中,它们返回map object而不是正确的列表,所以还有另一个List(map(lambda: ...)),这使得代码看起来对于每个高阶函数调用,到处都有大量括号真的很糟糕。

有没有一种pythonic方法可以做到这一点,同时仍然保持可读性?.append()尽管对我来说一点也不像pythonic,但我几乎要简化以使其具有可读性。

编辑:我真的需要一个列表列表,因为我会执行多次,读取多个表,然后可能将它们全部附加,所以请不要尝试更改代码结构的那部分。

编辑 2:这是我当前未过滤的输出。我的目标是过滤掉前两行。

[
 ['', '', '', ''],
 ['', '', 'Taxas de juros'],
 ['Posição', 'Instituição', '% a.m.', '% a.a.'],
 ['1', 'SINOSSERRA S/A - SCFI', '0,41', '5,03'],
 ['2', 'GRAZZIOTIN FINANCIADORA SA CFI', '0,84', '10,55'],
 ['3', 'BCO CATERPILLAR S.A.', '0,89', '11,27'],
 ['4', 'BCO VOLKSWAGEN S.A', '0,91', '11,49']
]

标签: pythonpython-3.xlist-comprehension

解决方案


我会做

[[td.text.strip() for td in tr.find_all('td')] 
 for tr in table.find_all('tr') 
 if tr.find('td').text.strip()]

因为tr.find('td')会返回第一个孩子td。剥离的文本要么有长度,要么没有。而在 Python 中,长度大于 0 的字符串的计算结果为 True。


推荐阅读