簡體   English   中英

如何根據值閾值過濾和刪除 dict 元素?

[英]How to filter and remove dict elements based on a value threshold?

我在具有這種結構的列表中有幾個字典:

[{'store': 'walmart',
  'store_id': 0,
  'store_info': {'grapes': {'availability': {'No': 1, 'Yes': 1}},
   'tomatoes': {'availability': {'No': 5, 'Yes': 6}},
   'oranges': {'availability': {'No': 2, 'Yes': 2}},
   'bottled water': {'availability': {'No': 10, 'Yes': 5}},
   "india's mangos": {'availability': {'No': 3, 'Yes': 5}},
   'water melon': {'availability': {'No': 2, 'Yes': 2}},
   'lemons': {'availability': {'No': 2, 'Yes': 3}},
   'kiwifruit': {'availability': {'No': 4, 'Yes': 2}},
   'pineapple': {'availability': {'No': 5, 'Yes': 20}},
   'total_yes': 23,
   'total_no': 23,
   'total': 46,
   'id': [3, 4, 6, 2, 1, 6, 1, 4, 2]}},
{'store': 'Costco',
  'store_id': 24,
  'store_info': {'papaya': {'availability': {'No': 1, 'Yes': 1}},
   'lychee': {'availability': {'No': 5, 'Yes': 1}},
   'fig': {'availability': {'No': 2, 'Yes': 2}},
   'blackberry': {'availability': {'No': 2, 'Yes': 5}},
   "india's mangos": {'availability': {'No': 3, 'Yes': 5}},
   'plum': {'availability': {'No': 1, 'Yes': 2}},
   'total_yes': 43,
   'total_no': 3,
   'total': 46,
   'id': [3, 4, 36, 2, 1, 1, 2, 4, 2]}}  
]

如何同時過濾所有大於或等於 5 的 Yes 和 No 值? 例如,給定上面的字典。 如果字典滿足條件,則預期的 output 應如下所示:

[
{'store': 'walmart',
  'store_id': 0,
  'store_info': {
  'tomatoes': {'availability': {'No': 5, 'Yes': 6}},
  'bottled water': {'availability': {'No': 10, 'Yes': 5}},
  'pineapple': {'availability': {'No': 5, 'Yes': 20}},
  'total_yes': 23,
  'total_no': 23,
  'total': 46,
  'id': [3, 4, 6, 2, 1, 6, 1, 4, 2]}
  }
]

在上面的例子中, 'india's mangos': {'availability': {'No': 3, 'Yes': 5}}應該被過濾或刪除。 因為,雖然 5 fullfil Yes 門檻,但關鍵 No,並沒有同時達成門檻。 或者, 'pineapple': {'availability': {'No': 5, 'Yes': 20}}應該保留在字典中,因為Yes鍵的值為 20,大於閾值 5。 最后,應該刪除第二個字典(costco),因為它的所有鍵都不是至少 5 個。

到目前為止,我試圖迭代結構,但是,我做了太多循環,有沒有更緊湊的方法來獲得預期的 output?:

a_lis = []
for e in list_dict:
    try:
        l = list(e['store_info'].keys())
        for i in l:
            #print(e['store_info'][i]['availability'])
            if e['store_info'][i]['availability']['No']>=5 and e['availability'][i]['availability']['Yes']>= 5:
                a_lis.append(e['store_info'][i]['availability'])
                print(a_lis)
            else:
                pass
    except TypeError:
        pass

這並不難。我建議您創建一個新列表。(並直接修改字典。)

lst = [{'store': 'walmart',
        'store_id': 0,
        'store_info': {'grapes': {'availability': {'No': 1, 'Yes': 1}},
                       'tomatoes': {'availability': {'No': 5, 'Yes': 6}},
                       'oranges': {'availability': {'No': 2, 'Yes': 2}},
                       'bottled water': {'availability': {'No': 10, 'Yes': 5}},
                       'india\'s mangos': {'availability': {'No': 3, 'Yes': 5}},
                       'water melon': {'availability': {'No': 2, 'Yes': 2}},
                       'lemons': {'availability': {'No': 2, 'Yes': 3}},
                       'kiwifruit': {'availability': {'No': 4, 'Yes': 2}},
                       'pineapple': {'availability': {'No': 5, 'Yes': 20}},
                       'total_yes': 23,
                       'total_no': 23,
                       'total': 46,
                       'id': [3, 4, 6, 2, 1, 6, 1, 4, 2]}},
       {'store': 'Costco',
        'store_id': 24,
        'store_info': {
            'papaya': {'availability': {'No': 1, 'Yes': 1}},
                       'lychee': {'availability': {'No': 5, 'Yes': 1}},
                       'fig': {'availability': {'No': 2, 'Yes': 2}},
                       'blackberry': {'availability': {'No': 2, 'Yes': 5}},
                       'india\'s mangos': {'availability': {'No': 3, 'Yes': 5}},
                       'plum': {'availability': {'No': 1, 'Yes': 2}},
                       'total_yes': 43,
                       'total_no': 3,
                       'total': 46,
                       'id': [3, 4, 36, 2, 1, 1, 2, 4, 2]}}
       ]

result_list = []
for sub_dict in lst:
    if sub_dict['store_info']['total_yes'] >= 5 and sub_dict['store_info']['total_no'] >= 5:
        result_list.append(sub_dict)
        key_need_to_be_removed = [k for k, v in sub_dict['store_info'].items() if type(v) is dict and (v['availability']['Yes'] < 5 or v['availability']['No'] < 5)]
        for k in key_need_to_be_removed: # remove the dict under dictionary['store_info']
            del sub_dict['store_info'][k]

print(result_list)

結果:

[{
    'store': 'walmart',
    'store_id': 0,
    'store_info': {
        'tomatoes': {
            'availability': {
                'No': 5,
                'Yes': 6
            }
        },
        'bottled water': {
            'availability': {
                'No': 10,
                'Yes': 5
            }
        },
        'pineapple': {
            'availability': {
                'No': 5,
                'Yes': 20
            }
        },
        'total_yes': 23,
        'total_no': 23,
        'total': 46,
        'id': [3, 4, 6, 2, 1, 6, 1, 4, 2]
    }
}]

這是另一種方法:

# where data is the input
filtered = []

for store in data:
    avail_dict = {}
    extra_dict = {}
    for item, value in store['store_info'].items():
        if isinstance(value, dict):
            okay = value['availability'].get('No',0) >= 5 and value['availability'].get('Yes',0) >= 5
            if okay:
                avail_dict[item] = value
        else:
            extra_dict[item] = value
    if avail_dict:
        avail_dict.update(extra_dict)
        new_store = dict(store)
        new_store['store_info'] = avail_dict
        filtered.append(new_store)

filtered結果(輸入data不變):

[{'store': 'walmart',
  'store_id': 0,
  'store_info': {'tomatoes': {'availability': {'No': 5, 'Yes': 6}},
   'bottled water': {'availability': {'No': 10, 'Yes': 5}},
   'pineapple': {'availability': {'No': 5, 'Yes': 20}},
   'total_yes': 23,
   'total_no': 23,
   'total': 46,
   'id': [3, 4, 6, 2, 1, 6, 1, 4, 2]}}]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM