Python 构建动态 if 条件 - 或/和

Tsv*_*lin 6 python dynamic filter conditional-statements

我有以下示例,其中从 JSON 格式过滤并打印数据:

arr = [
    {
        "EffectiveDate": "2018-05-01T00:00:00Z",
        "IncludedQuantity": 0.0,
        "MeterCategory": "VM",
        "Unit": "1 GB/Month",
        "MeterName": "P4 Disks"
    },
    {
        "EffectiveDate": "2018-03-14T00:00:00Z",
        "IncludedQuantity": 0.0,
        "MeterCategory": "Storage",
        "MeterName": "P4 Disks"
    },
    {
        "EffectiveDate": "2017-04-01T00:00:00Z",
        "IncludedQuantity": 0.0,
        "MeterCategory": "VM",
        "Unit": "1 Hour",
        "MeterName": "P4 Disks"
    }
]

def get_data(getarr):
    for data in getarr:
        if data['MeterCategory'] == "VM"\
            and data['MeterName'] == "P4 Disks"\
                and data['Unit'] == "1 GB/Month":
            print(data)

get_data(arr)
Run Code Online (Sandbox Code Playgroud)

我想在函数 get_data 中动态指定“AND”条件。假设我想在以下条件下运行函数 get_data :

示例 1. 仅按“MeterCategory”搜索:

if data['MeterCategory'] == "VM":
Run Code Online (Sandbox Code Playgroud)

示例 2. 按“MeterCategory”和“MeterName”搜索:

  if data['MeterCategory'] == "VM"\
           and data['MeterName'] == "P4 Disks":
Run Code Online (Sandbox Code Playgroud)

一种方法是使用语句组合来定义不同的函数,但如果我想动态控制 AND 运算符,我发现只有这种方法:

def get_data(getarr, filter_type):
    filters = None
    r1 = "obj['MeterName'] == 'P4 Disks'"
    r2 = "obj['MeterName'] == 'P4 Disks' and obj['MeterCategory'] == 'Storage'"

    if (filter_type == "filter1"): filters = r1
    if (filter_type == "filter2"): filters = r2

    data = [obj for obj in getarr if(eval(filters))]
    print(data)

get_data(arr, 'filter2')
Run Code Online (Sandbox Code Playgroud)

能否请您指教。谢谢!

Chr*_*yle 4

您可以将条件作为键和值的字典传递。然后在你的函数中循环它们,如果任何条件不满足,则中断循环,因为这是 AND 逻辑,所有条件都必须为真。因此,如果有任何失败,就中断并停止检查其他的。

假设所有条件都为 True,循环将成功完成,然后进入循环的 else 部分,这意味着我们可以打印数据,因为我们成功完成了所有条件。

arr = [
    {
        "EffectiveDate": "2018-05-01T00:00:00Z",
        "IncludedQuantity": 0.0,
        "MeterCategory": "VM",
        "Unit": "1 GB/Month",
        "MeterName": "P4 Disks"
    },
    {
        "EffectiveDate": "2018-03-14T00:00:00Z",
        "IncludedQuantity": 0.0,
        "MeterCategory": "Storage",
        "MeterName": "P4 Disks"
    },
    {
        "EffectiveDate": "2017-04-01T00:00:00Z",
        "IncludedQuantity": 0.0,
        "MeterCategory": "VM",
        "Unit": "1 Hour",
        "MeterName": "P4 Disks"
    }
]


def get_data(getarr, conditions):
    return_data = []
    for data in getarr:
        for key, value in conditions.items():
            if key in data and data[key] != value:
                break
        else:
            return_data.append(data)
    return return_data

print(get_data(arr, {"MeterCategory": "VM", "Unit": "1 GB/Month"}))
print(get_data(arr, {"MeterCategory": "VM"}))
print(get_data(arr, {"MeterCategory": "Storage"}))
Run Code Online (Sandbox Code Playgroud)

输出

[{'EffectiveDate': '2018-05-01T00:00:00Z', 'IncludedQuantity': 0.0, 'MeterCategory': 'VM', 'Unit': '1 GB/Month', 'MeterName': 'P4 Disks'}]
[{'EffectiveDate': '2018-05-01T00:00:00Z', 'IncludedQuantity': 0.0, 'MeterCategory': 'VM', 'Unit': '1 GB/Month', 'MeterName': 'P4 Disks'}, {'EffectiveDate': '2017-04-01T00:00:00Z', 'IncludedQuantity': 0.0, 'MeterCategory': 'VM', 'Unit': '1 Hour', 'MeterName': 'P4 Disks'}]
[{'EffectiveDate': '2018-03-14T00:00:00Z', 'IncludedQuantity': 0.0, 'MeterCategory': 'Storage', 'MeterName': 'P4 Disks'}]
Run Code Online (Sandbox Code Playgroud)