【问题标题】:call a method in map and lambda using dictionary as input in python使用字典作为python中的输入调用map和lambda中的方法
【发布时间】:2023-03-31 12:03:01
【问题描述】:
test_input = {"oneone": 1, "twotwo": 2, "threethree": 3}

def testmethod(no):
    print(f"Number {no}")
    return True, f"Number {no}"

不使用lambdamap

d = {}
for k, v in test_input.items():
    ret, out = testmethod(v)
    if ret:
        d[k] = out

我尝试使用lambdamap 进行迭代:

>>> dict(map(lambda ref: testmethod(ref), list(test_input.values())))
{True: 'Number 3'}

使用maplambda 的预期输出:

{'oneone': 'Number 1', 'twotwo': 'Number 2', 'threethree': 'Number 3'}

【问题讨论】:

  • testmethod() 总是返回 True 作为元组的第一个元素。您将此值用作字典中的键,并且在每次迭代时覆盖相应的字典值。
  • @bb1。你没有覆盖:这是一本新字典。另外,假装这只是一个例子
  • @MadPhysicist 字典是新的,但它是通过迭代元组 (True, some_value) 构建的。

标签: python dictionary lambda


【解决方案1】:

您可以按如下方式重写循环:

d = {}
for k, v in test_input.items():
    tup = testmethod(v)
    if tup[0]:
       d[k] = tup[1]

关键是打包和解包两个返回值会分散您的注意力,因为它们实际上是一个返回值。

将这种洞察力与海象运算符结合起来以合并赋值和条件行:

if (tup := testmethod(v))[0]:

现在你有了类似字典理解的东西:

d = {k: tup[1] for k, v in test_input.items() if (tup := testmethod(v))[0]}

如果您有旧版本的 python(3.8 之前),或者出于其他原因想要避免使用海象,则需要过滤结果。你的 lambda 放错了位置:lambda ref: testmethod(ref) 只是 testmethod 有额外的步骤。诀窍是在您完成映射后拆分流。然后,您可以使用 itertools.compress 之类的内容进行过滤:

from itertools import compress

rets, outs = zip(*map(testmethod, test_input.values()))
d = dict(compress(zip(test_input.keys(), outs), rets))

这是一个相当丑陋且效率低下的两线。作为一个班轮,你可以让它变得更糟。为此,您将rets, outs 变成一个列表,将其反转,然后在test_input.keys() 之后将其展开为一个zip,以创建一个产生key, value, filter 的迭代器:

d = {k: v for k, v, tf in zip(test_input. keys(), *list(zip(*map(testmethod, test_input.values())))[::-1]) if tf}

【讨论】:

  • @Barmar。假设需要过滤,非海象理解是可能的,但男孩是丑陋的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多