2011-02-03 13 views
3

Новым для программирования в целом, поэтому я, вероятно, ошибаюсь. Я пишу парсер lxml, где я хочу опустить строки таблицы HTML, у которых нет содержимого из вывода парсера. Это то, что я получил:Pythonic способ условно перебрать элементы в списке

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 в b, если a! = X», но это не работает.

Спасибо!

+0

Умм, что именно вы пытаетесь сделать? Разбор xml не является простым. Может, вам стоит попробовать что-то еще, так как вы только начинаете? Как насчет вас показать нам пример ввода/вывода – Falmarri

ответ

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

Единственная проблема заключается в том, что он не выравнивает вещи должным образом, так как он удаляет все пустые ячейки.Таким образом, одна строка может иметь 1 непустую ячейку и еще одну непустую ячейку, а у нее будет не табличное выравнивание. – troutinator

+0

@troutinator - я отредактировал ответ, теперь он печатает все или ничего. – eumiro

+0

Спот-он, спасибо. –

0

Пересоздать:

Вы знаете, я действительно не нравится мой ответ на все. Я голосовал до другого ответа, но мне понравился его оригинальный ответ, потому что не только это было чистым, но само за себя, не получая «фантазия», который является то, что я стал жертвой:

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

там не намного больше элегантного решения.

Original-иш:

Вы можете превратить вторую 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')) 

производит итератор, который вы можете перебор, пропуская все элементы, которые вы не хотите.

Edit:

И прежде чем я получаю больше downvotes, если вы используете Python 3.0, filter работает точно так же. Нет необходимости импортировать ifilter.

+0

Нет, вы не можете ... –

+0

Нет, вы не можете. Это работает только внутри списков. –

+0

Это проблема, с которой я столкнулся. Немного перефразированный вопрос, чтобы уточнить. –

Смежные вопросы