Pythonic方式有条件地迭代列表中的项目

时间:2011-02-03 18:50:05

标签: python lxml

一般来说是编程新手,所以我可能会以错误的方式解决这个问题。我正在编写一个lxml解析器,我想省略没有解析器输出内容的HTML表行。这就是我所拥有的:

for row in doc.cssselect('tr'):
    for cell in row.cssselect('td'):
        sys.stdout.write(cell.text_content() + '\t')
    sys.stdout.write '\n'

write()内容是暂时的。我想要的是循环只返回tr.text_content != ''的行。所以我想我要问的是如何编写我的大脑认为应该是'如果a!= x'中的b,但这不起作用。

谢谢!

2 个答案:

答案 0 :(得分:4)

for row in doc.cssselect('tr'):
    cells = [ cell.text_content() for cell in row.cssselect('td') ]
    if any(cells):
        sys.stdout.write('\t'.join(cells) + '\n')
仅当至少有一个包含文本内容的单元格时,

才会打印该行。

答案 1 :(得分:0)

<强>重新编辑

你知道,我真的不喜欢我的回答。我投了另一个答案,但我喜欢他原来的答案,因为它不仅是干净而且是自我解释而没有得到“幻想”,这是我成为受害者:

for row in doc.cssselect('tr'):
    for cell in row.cssselect('td'):
        if(cel.text_content() != ''):
            #do stuff here

没有更多优雅的解决方案。

<强>原始肥胖型

您可以按如下方式转换第二个for循环:

[cell for cell in row.cssselect if cell.text_content() != '']

并将其转换为列表理解。这样你就有了预先筛选的清单。通过查看以下示例,您可以更进一步:

a = [[1,2],[2,3],[3,4]
newList = [y for x in a for y in x]

将其转换为[1, 2, 2, 3, 3, 4]。然后,您可以在末尾添加if语句来筛选出值。因此,您可以将其缩减为一行。

然后再次,如果您要查看itertools

ifilter(lambda x: x.text_content() != '', row.cssselect('td'))

生成一个迭代器,你可以迭代它,跳过你不想要的所有项目。

修改

在我得到更多downvotes之前,如果你使用python 3.0,filter的工作方式相同。无需导入ifilter