【问题标题】:Can I insert a tuple (or a list) of arguments into a function using map? [duplicate]我可以使用 map 将参数的元组(或列表)插入到函数中吗? [复制]
【发布时间】:2020-05-27 17:59:05
【问题描述】:

我的目标是创建一个函数来检查一个数字是否在给定的范围内。

所以,我创建了一个函数 range_check(),它接受三个参数 - 数字、低和高。我还创建了 4 个存储为元组的测试用例。前三个测试用例为真,最后一个为假。

def range_check(num, low, high):
    return low <= num <= high


test_values = [(2, 1, 4), (5, 2, 7), (3, 1, 10), (3, 4, 5)]

for test_case in test_values:
    print(range_check(test_case[0], test_case[1], test_case[2]))

由于我最近发现了 lambda 是什么以及如何使用它(我对 Python 和一般编程仍然很陌生),我想尝试使用 lambda 和 map 来解决这个问题(或者过滤器也可以在这里使用,我猜)

test_values = [(2, 1, 4), (5, 2, 7), (3, 1, 10), (3, 4, 5)]
print(list(map(lambda num, low, high: low <= num <= high, test_values)))

但是,这会产生错误 - lambda 缺少 2 个必需的参数 - 低和高。

有什么方法可以将参数元组插入到这样的函数或 lambda 中?

我想出的唯一办法就是列出数字、低点和高点。

nums = [2, 5, 3, 3]
lows = [1, 2, 1, 4]
highs = [4, 7, 10, 5]

print(list(map(lambda num, low, high: low <= num <= high, nums, lows, highs)))

但在我看来,这似乎并不容易,以后可能很难理解。

非常感谢您提供任何帮助或想法。

【问题讨论】:

    标签: python function lambda


    【解决方案1】:

    lambda 函数无法自动解压缩参数。 maptuple 传递给函数,而不是 3 个参数。您必须将一个参数作为tuple 并访问元素:

    test_values = [(2, 1, 4), (5, 2, 7), (3, 1, 10), (3, 4, 5)]
    print(list(map(lambda t: t[1] <= t[0] <= t[2], test_values)))
    

    这就是为什么简单的列表理解要好得多:您可以在循环中解包元组:

    [low <= num <= high for num,low,high in test_values]
    

    它也更快,因为您不必链接函数调用,并且不那么神秘。 map + lambda 组合在速度和可读性方面并不是最好的。

    两者的结果都是[True, True, True, False]

    【讨论】:

    • 如果我想将 map 与普通函数一起使用,我是否应该只传递一个参数 - t?然后写 t[0] 而不是 number 等?
    • 但是感谢列表理解的想法,我认为这确实是最好的做法。
    • 是的,正常功能也一样
    【解决方案2】:

    您看到了将元组作为参数与将元组的 元素 作为单独参数之间的区别。你可以写

    print(list(map(lambda t: t[1] <= t[0] <= t[2], test_values)))
    

    或者您可以使用itertools.starmap,它可以有效地为您解包元组。

    from itertools import startup
    
    print(list(starmap(lambda num, low, high: low <= num <= high, test_values)))
    

    不过,在 Python 中,使用列表推导式构建列表通常比显式使用 map 和函数更清晰:

    print([low <= num <= high for num, low, high in test_values])
    

    【讨论】:

    • 使用理解不仅更清晰,而且通常更快。
    【解决方案3】:

    您可以使用zip 和元组解包:

        test_values = [(2, 1, 4), (5, 2, 7), (3, 1, 10), (3, 4, 5)]
    
        print(list(map(lambda num, low, high: low <= num <= high, *zip(*test_values))))
    

    返回 [True, True, True, False]

    我要补充一点,对于这类事情,列表推导式的可读性要高得多。就连 Guido 都讨厌map...

    【讨论】:

      【解决方案4】:

      我会用这样的 1 行 for 循环来做到这一点:

      print([range_check(*x) for x in test_values])
      

      函数参数中 x 前面的这个 * 使您的元组解压缩成更多变量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-12
        • 2022-01-16
        • 2012-02-24
        • 2023-04-10
        • 2019-11-18
        • 2015-02-25
        • 2019-02-09
        • 2018-09-30
        相关资源
        最近更新 更多