代码之家  ›  专栏  ›  技术社区  ›  jwalton

从列表[duplicate]创建lambda函数的方法

  •  1
  • jwalton  · 技术社区  · 7 年前

    前言

    pandas 和 numpy 包我相信解决方案不需要这些包中任何一个的工作知识。

    安装程序

    我希望创建一个lambda函数字典,以传递给 pandas pandas.DataFrame.to_latex .

    我希望lambda函数的字典能够将浮点数格式化为列表指定的位数。

    实例

    我想达到的目标,最好是以身作则。让我们设置一些要格式化的浮动:

    import numpy as np
    import pandas as pd
    
    y = np.array([[0.12345, 0.12345, 0.12345]])
    colnames = ['col1', 'col2', 'col3']
    df = pd.DataFrame(y, columns=colnames)
    
    #print(df)
    #      col1     col2     col3
    #0  0.12345  0.12345  0.12345
    

    很好,现在我想格式化这个专栏 col1 col2 在小数点后显示两位数字,并 col3 显示3位数字。让我们建立一个具有以下意图的列表:

    digits = [1, 2, 3]
    

    从这个列表中,我们将创建lambda函数的dict来格式化列,并在创建后测试函数。

    fun = {}
    
    for id, col in enumerate(['col1', 'col2', 'col3']):
        fun[col] = lambda x : '{{:.{}f}}'.format(digits[id]).format(x)
        print(fun[col](0.12345))
        # Prints 0.1, 0.12, 0.123 (looks to have worked!)
    

    在上面的代码中,在创建每个条目时打印出来,我已经实现了我想要的。然而,再看一遍,我发现我错了

    print(fun['col1'](0.12345)) # Prints 0.123
    print(fun['col2'](0.12345)) # Prints 0.123
    print(fun['col3'](0.12345)) # Prints 0.123
    

    digits[id] = 3 在循环之后。

    我想改变创建lambda函数的方式,这样我们就可以观察到:

    print(fun['col1'](0.12345)) # Prints 0.1
    print(fun['col2'](0.12345)) # Prints 0.12
    print(fun['col3'](0.12345)) # Prints 0.123
    

    有可能这样做吗?我想一个解决方案可能包括使用 eval

    显而易见的解决方案

    上下文之外 pd.DataFrame.to_latex ,我们可以创建一个lambda函数,该函数接受两个参数,并根据需要设置浮点格式:

    fun = lambda x, digit : '{{:.{}f}}'.format(digit).format(x)
    
    print(fun(0.12345, digits[0])) # Prints 0.1
    print(fun(0.12345, digits[1])) # Prints 0.12
    print(fun(0.12345, digits[2])) # Prints 0.123
    

    但是,据我所知,传递给 可能只需要一个论点,因此这样的解决方案是不可行的。

    1 回复  |  直到 7 年前
        1
  •  0
  •   attdona    7 年前

    您需要在循环时绑定float resolution的值,否则3个lambda闭包引用相同的值 id 变量,并且所有变量都将最后一个值指定给 .

    一个可能的解决方案是使用 functools.partial

    def col_resolution(resolution, x):
        return '{{:.{}f}}'.format(resolution).format(x)
    
    for id, col in enumerate(['col1', 'col2', 'col3']):
        fun[col] = partial(col_resolution, digits[id])
    
        # one line with lambda
        # fun[col] = partial(lambda res, x : '{{:.{}f}}'.format(res).format(x), digits[id])