Я думаю, что всегда приятно привести пример того, как это сделать с реальным парсером, а также просто повторить звуковой совет, который Эли Бендерский дает в своем ответе.
Вот пример того, как удалить пустые <p>
элементы, используя lxml .HTMLParser
в lxml отлично работает с HTML.
from lxml import etree
from StringIO import StringIO
input = '''This <p> </p><p>is a test</p><p></p><p><b>Bye.</b></p>'''
parser = etree.HTMLParser()
tree = etree.parse(StringIO(input), parser)
for p in tree.xpath("//p"):
if len(p):
continue
t = p.text
if not (t and t.strip()):
p.getparent().remove(p)
print etree.tostring(tree.getroot(), pretty_print=True)
..., который выдает:
<html>
<body>
<p>This </p>
<p>is a test</p>
<p>
<b>Bye.</b>
</p>
</body>
</html>
Обратите внимание, что при ответе на этот вопрос я неправильно прочитал вопрос,и я только удаляю пустые элементы <p>
, а не заменяю их на  
.С lxml я не уверен в простом способе сделать это, поэтому я создал еще один вопрос: