【问题标题】:Is it valid to use conditional expressions for side effects?对副作用使用条件表达式是否有效?
【发布时间】:2015-09-08 09:35:45
【问题描述】:

我正在尝试找出最好的方法是:

resource['contents'][media_type] = []
resource['contents'][media_type].append(row[0].toPython()) if row[0] is not None else None
resource['contents'][media_type].append(row[2].toPython()) if row[2] is not None else None

我认为代码很简单;如果行有一个值,则将它们添加到列表中。这种方法被认为可以吗?还有其他更好的方法吗? toPython 方法将返回包含对象的字符串描述。

【问题讨论】:

  • 不,这不被认为是好的。使用三元来表示副作用是一种非常奇怪的方法,使代码更难阅读(并且给你很长的行)。
  • 如果值可用,你想添加如果值不可用你想做的事情
  • @VigneshKalai 如果它不可用,我根本不添加任何东西
  • @Giannis 为什么不使用普通条件运算符而不是三元运算符
  • @jonrsharpe 我认为代码的错误部分是使用表达式来表示其副作用。它与旧的map(side_effectful_function, range(10)) 相同,而不是for i in range(10): side_effectful_function(i)

标签: python python-3.x


【解决方案1】:

对副作用使用“三元”conditional expression (x if C else y) 根本不是 Pythonic。以下是我的做法:

resource['contents'][media_type] = []
for index in (0, 2):
    item = row[i]
    if item is not None:
        resource['contents'][media_type].append(item.toPython())

或使用列表推导来减少冗长:

resource['contents'][media_type] = [row[i].toPython() for i in (0, 2) 
                                    if row[i] is not None]

这些方法更具可读性,并且减少了重复。

【讨论】:

  • 总是忘记列表理解。谢谢
  • 另外,是否建议我包含 is not None ?来自 groovy 我通常会省略它
  • @Giannis 是的,它是;请参阅python.org/dev/peps/pep-0008/#programming-recommendations的第二个要点
  • 我觉得for item in (row[0], row[2]):会更清楚一点。
  • @jpmc26 这很公平;我觉得这有点重复,并注意你可以参数化索引(你不能用 row[0], row[2] 做)。
【解决方案2】:

不,这不是条件表达式的有效使用。它会使任何试图阅读您的代码的人感到困惑。

使用if 语句;您可以通过创建对列表的另一个引用来节省一些空间:

lst = resource['contents'][media_type] = []
if row[0] is not None: lst.append(row[0].toPython()) 
if row[2] is not None: lst.append(row[2].toPython())

但为本地引用使用更好的名称(contents 或许?),或者使用列表推导:

resource['contents'][media_type] = [
    col.toPython() for col in (row[0], row[2]) if col is not None]

【讨论】:

    【解决方案3】:

    我不认为这样做是好的做法。你可以做的是:

    resource['contents'][media_type] = []
    
    for irow in [0, 2]:
        if row[irow] is not None:
            resource['contents'][media_type].append(row[irow].toPython())
    

    这使您可以灵活地使用范围(range(5) 中的 irow),或者如果您可以直接访问它们,则使用行 (for row in rows:)。

    【讨论】:

    • 这对现有的两个答案有何影响?
    • 我在收到任何回复之前就打开了帖子。当时,OP以下只有两个cmets。我认为你的回答是正确的。
    • 你用的是什么浏览器?添加或编辑答案时,任何相对现代的东西都会向您显示横幅。
    • 我正在使用 Chrome。如果您在另一个选项卡中,它们会出现吗?他们熬夜多久?如果向下滚动,它们会出现吗?横幅是否受广告屏蔽影响?我不记得看到过任何东西,但从现在开始我会留意的。
    • 我不这么认为;我使用 AdBlock,它们会为我出现。新的答案横幅出现在答案部分的顶部(如果您在没有任何答案时开始,它将直接在您的答案上方),编辑后的答案横幅出现在相关答案的顶部。
    猜你喜欢
    • 1970-01-01
    • 2013-12-23
    • 1970-01-01
    • 1970-01-01
    • 2014-09-19
    • 2013-11-15
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多