一种更加“pythonic”的方法来“检查无并处理它”

时间:2012-06-11 00:20:02

标签: string coding-style python

我有list dict个密钥['name','content','summary',...]。所有值都是字符串。但有些值是None。我需要删除contentsummary和其他一些键中的所有新行。所以,我这样做:

...
...
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”或更好的方法呢?

感谢。

8 个答案:

答案 0 :(得分:7)

代码对你来说很笨拙,但部分原因是因为你在重复自己。这样更好:

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'])

答案 1 :(得分:6)

如果您要使用标记值(无),那么您将负担检查它们的负担。

你的问题有很多不同的答案,但它们似乎忽略了这一点:当没有条目编码相同的信息时,不要在字典中使用sentinel值。

例如:

bibliography = [
    { 'name': 'bdhar', 'summary': 'questioner' },
    { 'name': 'msw', 'content': 'an answer' },
]

然后你可以

for article in bibliography:
    for key in article:
        ...

然后你的循环很好地不知道给定文章中包含哪些键(如果有的话)。

在阅读您的评论时,您声称自己正在从其他地方获取该词典。所以先清理它的垃圾值。如果有一个清洁步骤,那么很多更清楚,那就是通过你的代码来解决他们的误解。

答案 2 :(得分:5)

Python有一个ternary operator,所以一个选项是以更自然的单词顺序执行此操作:

content = content.replace('\n', '') if content is not None else None

请注意,如果""None在您的情况下是相同的(看起来是这样),您可以将其缩短为if content,因为非空字符串计算为{ {1}}。

True

这也遵循显式的Python习语比隐式更好。这表示有人遵循代码,该值可以非常清楚content = content.replace('\n', '') if content else None

值得注意的是,如果你重复这个操作,可能值得将它封装为一个函数。

Python中的另一个习语是请求宽恕,而不是许可。因此,您可以简单地使用Nonetry后面的except,但是,在这种情况下,这会变得更加冗长,所以它可能不值得,特别是作为检查是如此之小。

AttributeError

答案 3 :(得分:2)

一种可能性是使用空字符串而不是None。这不是一个完全通用的解决方案,但在许多情况下,如果您的数据都是单一类型,那么除了None(空字符串,空列表,零等)之外,还会有一个合理的“空”值。在这种情况下,看起来你可以使用空字符串。

答案 4 :(得分:2)

尝试:

if content: content = content.replace('\n','')

-

只要if content包含除0,False或None之外的任何内容,

True将(几乎 1 )始终为content


1 正如Lattyware在评论中正确指出的那样,这不是严格的True。在False语句中还有其他内容将评估为if,例如,空列表。请参阅以下评论中提供的链接。

答案 5 :(得分:2)

空字符串在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

答案 6 :(得分:2)

您也可以考虑将一些if子句抽象为一个单独的函数:

def remove_newlines(mystr):
    if mystr:
        mystr = mystr.replace('\n')
    return mystr

(编辑以删除带有词典的过于复杂的解决方案等)

答案 7 :(得分:1)

我认为“pythonic”的事情是使用None在if语句中将评估为False的事实。 所以你可以说:

if content: content = content.replace('\n','')