【问题标题】:Alternative solution not using closures不使用闭包的替代解决方案
【发布时间】:2021-09-23 19:09:50
【问题描述】:

我有一个类 Data 我想使用下面的 api 过滤它。

# Example: filter using where
inpt = {"a":np.array((1,2,3,4,2,5,6,2,3,3,2,1)), 
         "b":np.random.rand(12)}
data = (Data(inpt)
        .where(col("a").equals(3)) # This is how where should be called. 
       )
data
  • where 是类 Data 中的一个方法
  • col("a").equals(3)inpt["a"] == 3 的语法糖

我可以使用另一个类Expr 来实现这一点,该类使用闭包处理Data.where() 中的所有功能。原因是Expr 无权访问Data

问题:有人可以为我提供不涉及闭包的替代方法吗?我的目标是学习新的方法/方向。

这是我的代码:

from __future__ import annotations
from typing import Dict, Any
import numpy as np

class Data:
    def __init__(self, data: Dict):
        self._data = data
        
    def where(self, e: Expr) -> Data:
        idx = e.collect(self)
        for k,v in self._data.items():
            self._data[k] = v[idx]
        return self
    
    def __repr__(self):
        return str(self._data)

class Expr:
    def __init__(self):
        self.fs = []
        
    
    def col(self, s: str) -> Self:
        f = lambda x: x._data[s]
        self.fs.append(f)
        return self

    def equals(self, el: Any) -> Self:
        f = lambda x: x == el
        self.fs.append(f)
        return self
        

    def collect(self, x: Data) -> Data:
        args = x
        for f in self.fs:
            args = f(args)
        return args
    
def col(s: str) -> Expr:
    return Expr().col(s)

【问题讨论】:

    标签: python-3.x closures


    【解决方案1】:

    我真的不明白这一点。如果你举一个你实际尝试做的例子?

    如果您已经知道正确的密钥,您可以直接检查。如果你想找到正确的键,pythonic 方法是使用列表推导。

    In [2]: inpt = {
       ...:     "a": (1,2,3,4,2,5,6,2,3,3,2,1),
       ...:     "b": 3,
       ...: }
    
    In [3]: inpt["a"] == 3
    Out[3]: False
    
    In [4]: inpt["b"] == 3
    Out[4]: True
    
    In [5]: [key for key, value in inpt.items() if value == 3][0]
    Out[5]: 'b'
    
    In [8]: from typing import Sequence
    
    In [9]: [key for key, value in inpt.items() if isinstance(value, Sequence) and 3 in value][0]
    Out[9]: 'a'
    
    
    
    

    【讨论】:

    • 感谢您的回复。非常感谢!我的问题不是我不知道钥匙。我的挣扎是我想以我可以调用Data(...).where(col("a").equals(3)) 的方式实现该方法。这就是我最终想要达到的目标。我的问题是如何以我的解决方案的替代方式在幕后实现这一点。
    • 附带说明:函数equals(3) 只是一个简单的函数。我想创建许多可以这样调用的不同函数。
    • 我的问题是 col("a").equals(3)Data 类是分开的,这就是为什么我需要使用闭包传递实际数据的原因。感谢其他方法!
    • 我知道这就是你想要的语法。但我是说它不是 Pythonic,如果你解释了你要解决的问题,几乎可以肯定有更好的方法来解决。您目前有一些可行的方法,my previous answer 是可扩展的替代解决方案。我不太确定您还在寻找什么。
    猜你喜欢
    • 1970-01-01
    • 2011-04-13
    • 2016-10-24
    • 2012-10-11
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 2010-11-27
    相关资源
    最近更新 更多