3

我有一个listwith dictkeys ['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”或更好的方法来做到这一点?

谢谢。

4

8 回答 8

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'])
于 2012-06-11T00:26:19.303 回答
6

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

您的问题有很多不同的答案,但他们似乎错过了这一点:当没有条目编码相同的信息时,不要在字典中使用哨兵值。

例如:

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

那么你就可以

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

然后您的循环完全不知道给定文章中包含哪些键(如果有)。

在阅读您的评论时,您声称您从其他地方获得了 dict。所以首先清除它的垃圾值。有一个清理步骤比通过你的代码传达他们的误解要清楚得多。

于 2012-06-11T00:48:15.443 回答
5

Python 有一个三元运算符,因此一种选择是以更自然的词序来执行此操作:

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

请注意,如果""None在您的情况下是等效的(看起来是这样),您可以将其缩短为 just if content,因为非空字符串评估为True

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

这也遵循 Python 的显式优于隐式的习语。这表明有人按照代码可以None很清楚地看到该值。

值得注意的是,如果您经常重复此操作,则可能值得将其封装为一个函数。

Python 中的另一个习语是请求宽恕,而不是许可。所以你可以简单地使用tryand ,但是,exceptAttributeError这种情况下,这变得更加冗长,所以它可能不值得,特别是因为检查的成本是如此之小。

try:
    content = content.replace('\n', '')
except AttributeError:
    content = None
    #pass #Also an option, but as mentioned above, explicit is generally clearer than implicit.
于 2012-06-11T00:22:31.473 回答
2

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

于 2012-06-11T00:22:43.350 回答
2

尝试:

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

--

if content将(几乎1)总是True只要content包含除 0、False 或 None 之外的任何内容。


1正如 Lattyware 在评论中正确指出的那样,这并不完全正确。还有其他的东西会Falseif语句中计算,例如,一个空列表。请参阅下面评论中提供的链接。

于 2012-06-11T00:23:00.000 回答
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
于 2012-06-11T00:24:20.327 回答
2

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

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

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

于 2012-06-11T00:32:13.553 回答
1

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

if content: content = content.replace('\n','')
于 2012-06-11T00:24:25.363 回答