如何打印导致函数最大值的变量值?

时间:2018-03-22 19:08:03

标签: python python-3.x function math max

我想在python中计算函数的最大值,然后打印最大值,以及最大值的变量值。

我想我已经走得很远了。在下面的示例中,函数只是x的值乘以y的值乘以z的值(理论上此函数可以是任何值)。最大值为3 * 6 * 9 = 162

我的问题是:如果这些列表长达数百个,我真的不想打印整个输入列表,这可能是数十万个条目的大量列表。

我只对最终的一组值感兴趣(所以这里3 6 9),但我似乎无法弄清楚如何只打印这一组。

非常感谢任何帮助。

谢谢!

p=[1,2,3]
q=[6,5,4]
r=[7,8,9]

def f(x,y,z):
    maximum=0
    for a in x:
        for b in y:
            for c in z:
                if a*b*c > maximum:
                    maximum = a*b*c
                    print (a,b,c)
    print (maximum)  

f(p,q,r)

结果:

1 6 7
1 6 8
1 6 9
2 6 7
2 6 8
2 6 9
3 6 7
3 6 8
3 6 9
162

3 个答案:

答案 0 :(得分:3)

原来写出你的问题是解决问题的好方法。不管怎样,谢谢!

def f(x,y,z):
    maximum=0
    for a in x:
        for b in y:
            for c in z:
                if a*b*c > maximum:
                    j=(a,b,c)
                    maximum = a*b*c
    print (maximum)
    print (j)

答案 1 :(得分:3)

最简单的方法是以跟踪当前最大值的方式跟踪值:

def f(x,y,z):
    maximum = 0
    for a in x:
        for b in y:
            for c in z:
                if a*b*c > maximum:
                    maximum = a*b*c
                    a_max = a
                    b_max = b
                    c_max = c
    print(a_max,b_max,c_max)
    print(maximum)

通过使用与开头设置maximum = 0不同的技术,您可以使代码更加健壮。例如,如果您的列表只有负数怎么办?结果将是错误的。您可以使用所谓的标记值(如None)来指示第一次迭代。哨兵是一个标记,表示"无效"值。这将确保始终找到正确的最大值:

def f(x,y,z):
    maximum = None
    for a in x:
        for b in y:
            for c in z:
                if maximum is None or a*b*c > maximum:
                    maximum = a*b*c
                    abc_max = (a, b, c)
    print (*abc_max, sep=', ')
    print (maximum)

您可以通过返回您感兴趣的数字来改进代码的设计,而不仅仅是打印它们。这将允许您以任何您想要的方式操纵它们,包括之后打印它们。 Python允许使用元组的多个返回值,因此您可以执行以下操作:

def f(x,y,z):
    maximum = None
    for a in x:
        for b in y:
            for c in z:
                if maximum is None or a*b*c > maximum:
                    maximum = a*b*c
                    abc_max = (a, b, c)
    return maximum, abc_max

max, pqr = f(p, q, r)
print(*pqr, sep=', ')
print(max)

您可能想要考虑的优化不是评估您的"功能"不止一次。这对于不会两次返回相同值的更复杂的情况和功能尤为重要。您可以使用

之类的内容替换if块的开头
...
current_value = a * b * c
if current_value > maximum:
    maximum = current_value
    ...

如果您真的对使用任意函数进行此工作感兴趣,可以使用Python来执行此操作。函数是对象,可以像列表,数字和字符串一样传递:

def f(fn, x, y, z):
    maximum = None
    for a in x:
        for b in y:
            for c in z:
                current = fn(a, b, c)
                if maximum is None or current > maximum:
                    maximum = current
                    abc_max = (a, b, c)
    return maximum, abc_max

max, pqr = f(lambda x, y, z: x * y * z, p, q, r)

如果您对进一步的概括感兴趣,可以查看itertools,它具有product功能,用于运行"展平"嵌套for循环的版本。这将允许您接受任意数量的输入迭代,而不仅仅是三个。 Python允许在参数列表中使用*的任意数量的位置参数。名称中带有*的参数将是所有剩余位置参数的元组。它也可以用在lambda中:

from functools import reduce
from itertools import product
from operator import mul

def f(fn, *iterables):
    max_values = max(product(*iterables), key=lambda x: fn(*x))
    return fn(*max_values), max_values

max, pqr = f(lambda *args: reduce(mul, args), p, q, r)

您可以考虑添加一个比较器来执行除计算最大值之外的其他操作。但是,这实际上是过度的,因为您可以使用正确实现的fn将任何其他操作转换为最大计算。这与用密钥而不是比较器实现Pythons排序函数的逻辑相同。在上面的示例中,您可以通过翻转键的符号找到最小值:lambda *args: -reduce(mul, args)。您可以找到其产品与其最接近的组合,例如lambda *args: -abs(sum(args) - reduce(mul, args))。可能性很大。

以下是IDEOne示例的链接,该示例演示了上面显示的上一个版本:https://ideone.com/QNj55T。 IDEOne是一个用于炫耀或测试小片段的便利工具。我与它没有任何关系,但我经常使用它。

答案 2 :(得分:2)

这是一个更精简的解决方案和pythonic,因为您希望这是一个学习示例。我也做了很多评论,所以你可以跟进:

# importing this is necessary in python3 as `reduce` was removed in python3
import functools

p = [1,2,3]
q = [6,5,4]
r = [7,8,9]

def f (x,y,z):

    # 1. Combine the list arguments together into 1 list "[x,y,z]"
    # 2. Iterate over each list in the group of lists "for li in [x,y,z]"
    # 3. Get the max number within each list "max(li)"
    # 4. Assign the resulting list to the maxv variable "maxv = ..." yielding [3,6,9]
    maxv = [max(li) for li in [x,y,z]]

    # Print the 3 largest integers used to multiply next
    print( maxv )

    # Use reduce to multiply each list element by themselves
    product = functools.reduce(lambda x,y: x*y, maxv)

    # Print the output = 162 in this case
    print( product )

f(p,q,r)    

更新

如果您不知道有多少整数列表将被传递到函数中(可能超过3个),您可以迭代整个参数处理程序并将其作为列表而不是编码{{1} },像这样:

[x,y,z]