我有一个dict
list
,键['name','content','summary',...]
。所有值都是字符串。但是有些价值观是None
.我需要删除content
、summary
和其他一些键中的所有新行。所以,我这样做:
...
...
for item in item_list:
name = item['name']
content = item['content']
if content is not None: content = content.replace('n','')
summary = item['summary']
if summary is not None: summary = summary.replace('n','')
...
...
...
...
我有点觉得if x is not None: x = x.replace('n','')
成语不是那么聪明或干净。有没有更"pythonic"或更好的方法?
谢谢。
代码对你来说感觉很笨拙,但部分原因是因为你在重复自己。这样更好:
def remove_newlines(text):
if text is not None:
return text.replace('n', '')
for item in item_list:
name = item['name']
content = remove_newlines(item['content'])
summary = remove_newlines(item['summary'])
如果你打算使用哨兵值(None),那么你将承担检查它们的负担。
你的问题有很多不同的答案,但他们似乎忽略了这一点:当缺少条目编码相同的信息时,不要在字典中使用哨兵值。
例如:
bibliography = [
{ 'name': 'bdhar', 'summary': 'questioner' },
{ 'name': 'msw', 'content': 'an answer' },
]
然后你可以
for article in bibliography:
for key in article:
...
然后你的循环很好地忽略了给定文章中包含哪些键(如果有的话)。
在阅读您的评论时,您声称您是从其他地方获得的字典。所以先清理垃圾值。有一个清理步骤比通过你的代码传达他们的误解要清楚得多。
Python 有一个三元运算符,所以一种选择是以更自然的词序执行此操作:
content = content.replace('n', '') if content is not None else None
请注意,如果 ""
和 None
在您的情况下是等效的(似乎是这样),您可以将其缩短为仅 if content
,因为非空字符串的计算结果为 True
。
content = content.replace('n', '') if content else None
这也遵循了Python习语"显式优于隐式"。这向遵循代码的人表明,该值可以非常清楚地None
。
值得注意的是,如果您多次重复此操作,则可能值得将其封装为函数。
Python中的另一个成语是请求宽恕,而不是许可。因此,您可以简单地使用try
并except
随后的AttributeError
,但是,在这种情况下,这变得更加冗长,因此可能不值得,尤其是因为检查成本如此之小。
try:
content = content.replace('n', '')
except AttributeError:
content = None
#pass #Also an option, but as mentioned above, explicit is generally clearer than implicit.
一种可能性是使用空字符串而不是 None。 这不是一个完全通用的解决方案,但在许多情况下,如果你的数据都是单一类型,除了 None 之外,还会有一个合理的"null"值(空字符串、空列表、零等)。 在这种情况下,看起来您可以使用空字符串。
空字符串在 Python 中的计算结果为 False,因此 Pythonic 的方式是 if content:
。
In [2]: bool("")
Out[2]: False
In [3]: bool("hello")
Out[3]: True
旁注,但你可以让你的代码更清晰一点:
name, content = item["name"], item["content"]
和:
content = content.replace('n','') if content else None
你也可以考虑将一些if子句抽象到一个单独的函数中:
def remove_newlines(mystr):
if mystr:
mystr = mystr.replace('n')
return mystr
(编辑以删除带有字典等的过于复杂的解决方案)
尝试:
if content: content = content.replace('n','')
--
if content
将(几乎1)始终True
,只要 content
包含除 0、False 或 None 之外的任何内容。
1正如 Lattyware 在评论中正确指出的那样,这并不完全正确。还有其他一些内容将在 if
语句中计算False
,例如,空列表。请参阅下面评论中提供的链接。
我认为"pythonic"的事情是在if语句中使用None将计算为False的事实。所以你可以说:
if content: content = content.replace('n','')