Python:如何在理解表达式中重用表达式?

问题描述 投票:0回答:2

想象一个理论片段:

# just for this example: `bad_structure` contains a list of dicts with different keys
# for the same semantic
bad_structure = [{'path': '/dir/one'}, {'subdir': '/dir/two'}]

# i want to turn this into
# { '/dir/one': some_func('/dir/one'),
#   '/dir/two': some_func('/dir/two')}

result = {}
for e in bad_structure:
  # calculate a value which we will need more than once (here the key)
  p = next(k for k in ('path', 'subdir') if k in e)
  result[p] = some_func(p)

我现在想将其转变为字典理解,而我的第一个方法是这样的:

bad_structure = [{'path': '/dir/one'}, {'path': '/dir/two'}]
result = {next(k for k in ('path', 'subdir') if k in e): 
          some_func(next(k for k in ('path', 'subdir') if k in e))
          for e in bad_structure}

其中包含两次“计算”,这很丑陋,容易出错且运行缓慢。我想将其重写为s.th。喜欢

result = {p: some_func(p) 
          for p = next(k for k in ('path', 'subdir') if k in e)
          for e in bad_structure}

这当然不是有效的Python代码。

在Python中这样的事情可能吗?

为了澄清:我不在乎理解语法,但reusing没有单独的变量声明的计算(在封闭表达式中是不可能的)

python python-3.x dictionary-comprehension closed-expressions
2个回答
1
投票

是的! Python 3.8引入了“赋值运算符” :=,可让您在单个表达式的本地范围内定义变量(例如,理解)。在您的示例中,您将执行以下操作:

result = {(p := next(k for k in ('path', 'subdir') if k in e)): some_func(p) 
          for e in bad_structure}

免责声明:这不适用于3.8之前的任何版本的python。


1
投票

您可以使用中间理解来绑定到名称:

result = {
    p: some_func(p)
    # bind intermediate result to p
    for p in (  # nested comprehension to produce intermediate result
        next(k for k in ('path', 'subdir') if k in e)
        for e in bad_structure
    )
 }

而不是直接映射到两个单独的表达式,它首先映射到一个公共表达式,而then被映射到两个单独的表达式。

您可以传递并重命名任意数量的值。在内部理解中创建一个元组,然后在外部理解中将其解压缩为多个名称。

result = {
    p: some_func(e, p)
    # bind intermediate result to p
    for e, p in (  # nested comprehension to produce intermediate result
        (e, next(iter(e)))
        for e in bad_structure
    )
 }
© www.soinside.com 2019 - 2024. All rights reserved.