Python 使用带有 for 循环的三元运算符

Posted

技术标签:

【中文标题】Python 使用带有 for 循环的三元运算符【英文标题】:Python use ternary operator with for loop 【发布时间】:2021-07-18 16:17:36 【问题描述】:

我正在尝试改变它

def opt_config(opts):
    for x, x2 in opts:
        if x == "--config":
            return x2
    return str()

使用三元运算符

return x2 if x == "--config" for x, x2 in opts else str()

但它似乎不起作用。我该如何纠正?

【问题讨论】:

【参考方案1】:

这有几个部分。

str() 的后备返回将始终给出'',因为您要求它提供字面上没有的字符串值。如果这是您想要的,您不妨返回 ''

除非您的所有 opts 都是 2 元组(或其他每个具有 2 个元素的可迭代对象),否则任何单例 opt 都将在 for x, x2 in opts 处失败。猜测一下,您更有可能向此函数提供字符串列表,例如

opt_config(['--config', 'elderberries', 'castle']) -> 'elderberries'
opt_config(['grail', 'swallow', '--config', 'rabbit']) -> 'rabbit'
opt_config(['parrot', 'cheese', 'Olympics']) -> ''

再次,推测您想要什么,看来您想要第一个配置选项(并且只有第一个),或者如果 '--config' 从未出现,则 ''

如果我对您的意图的解释是正确的,那么对于代码的“非三元”版本,您可能想要这样的东西:

def opt_config(opts):
    if '--config' in opts:
        ndx = opts.index('--config')
        if ndx < len(opts):
            return opts[ndx + 1]
    return ''

opt_config(['--config', 'elderberries', 'castle'])
'elderberries'

opt_config(['grail', 'swallow', '--config', 'rabbit'])
'rabbit'

opt_config(['parrot', 'cheese', 'Olympics'])
''

如果您想压缩该代码,您可以使用您询问的三元运算符将其一直到 1-liner:

opt_config2 = lambda opts: opts[opts.index('--config') + 1] if '--config' in opts[:-1] else ''

opt_config2(['--config', 'elderberries', 'castle'])
'elderberries'

opt_config2(['grail', 'swallow', '--config', 'rabbit'])
'rabbit'

opt_config2(['parrot', 'cheese', 'Olympics'])
''

使用三元运算符x if y else z,首先计算if y 部分,因此python 仅根据需要有效地计算xz 选项之一。

【讨论】:

我会考虑这次重构,谢谢【参考方案2】:

您必须为此使用生成器表达式:

return next((x2 for x, x2 in opts if x == "--config"), str())

表达式(x2 for x, x2 in opts if x == 1) 是一个生成器:它 可用于迭代一组元素。例如:

opts = [(1, 2), (1, 3), (2, 4)]
gen = (x2 for x, x2 in opts if x == 1)
for x in gen:
  print(x)  #  print 2 and 3

next 返回生成器的下一个元素(或者如果你 暂时没有生成任何元素)。

如果生成器不包含任何下一个元素,那么第二个 (可选)next 的参数被返回。否则会引发异常。例如:

opts = [(1, 2), (2, 3)]

gen = (x2 for x, x2 in opts if x == 4)
x = next(gen)  #  raise StopIteration

gen = (x2 for x, x2 in opts if x == 4)
x = next(gen, 5)
print(x)  # print 5

总而言之,return next((x2 for x, x2 in opts if x == "--config"), str()) 相当于您的 for 循环:使用您的生成器,您获取 opts 的第一个元素 x, x2 使得 x == "--config" 并返回 x2 ;如果没有这样的元素,则返回str()

【讨论】:

添加了一些解释。希望这会有所帮助。 谢谢。你认为这是pythonic解决方案吗? 在我看来,pythonic 意味着简单易读。因此,简单的 for 循环解决方案可能比生成器更好,因为您可以直接理解其逻辑,而生成器需要更多的脑力劳动。 我同意你的考虑。

以上是关于Python 使用带有 for 循环的三元运算符的主要内容,如果未能解决你的问题,请参考以下文章

在“for”循环条件中使用“三元运算”是一种好习惯吗?

Python推导式

Python-yield 三元运算 Lambda表达式

For循环中的三元运算符导致无限迭代

逻辑运算符三元运算符for循环stack(栈),heap(堆),方法区,静态域

Python之路5-流程控制和三元运算