Python build Dynami c, если условия - или / и - PullRequest
0 голосов
/ 24 марта 2020

У меня есть следующий пример, где фильтрация из 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)

Я хочу динамически указать условия «И» в функции get_data. Допустим, я хочу запустить функцию get_data со следующими условиями:

пример 1. Поиск только по 'MeterCategory':

if data['MeterCategory'] == "VM":

пример 2. Поиск по 'MeterCategory' и 'MeterName':

  if data['MeterCategory'] == "VM"\
           and data['MeterName'] == "P4 Disks":

Одним из способов является определение различных функций с помощью комбинации операторов, но если я хочу динамически управлять операторами 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')

Можете ли вы дать совет. Спасибо!

1 Ответ

0 голосов
/ 24 марта 2020

Вы можете передать ваши условия в виде словаря ключей и значений. Тогда в вашей функции просто l oop над ними, если какое-либо из ваших условий не выполнено, тогда нарушите l oop, так как это логическое AND И c все условия должны быть выполнены. Так что если что-то не получится, просто сломайте и перестаньте проверять остальных.

При условии, что все условия выполнены, l oop будет успешно завершен, а затем введет остальную часть l oop, означая, что мы можем напечатать данные, поскольку мы успешно выполнили все условия.

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"}))

ВЫХОД

[{'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'}]
...