Как удалить указанные c значения из вложенного словаря? - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть вложенный словарь, dict1 следующим образом:

      {'pic1': {'filename': 'pic1.png',
      'size': 545,
      'regions': [{'shape_attributes': {'name': 'polygon',
      'x_values': [211, 205, 214, 232, 254, 263, 265, 265, 263, 257, 221],
      'y_values': [186, 200, 214, 218, 214, 204, 198, 190, 187, 181, 180]},
      'type': {'animal': '1'}},
      {'shape_attributes': {'name': 'polygon',
      'x_values': [272, 266, 275, 293, 315, 324, 326, 326, 324, 318, 282],
      'y_values': [233, 247, 261, 265, 261, 251, 245, 237, 234, 228, 227]},
      'type': {'animal': '2'}},
      {'shape_attributes': {'name': 'polygon',
      'x_values': [366, 360, 369, 387, 409, 418, 420, 420, 418, 412, 376],
      'y_values': [315, 329, 343, 347, 343, 333, 327, 319, 316, 310, 309]},
      'type': {'animal': '2'}},
      {'shape_attributes': {'name': 'polygon',
      'x_values': [201, 195, 204, 222, 244, 253, 255, 255, 253, 247, 211],
      'y_values': [224, 238, 252, 256, 252, 242, 236, 228, 225, 219, 218]},
      'type': {'animal': '3'}}],
      'file_attributes': {}},
      'pic2': {'filename': 'pic2.png',
      'size': 456,
      'regions': [{'shape_attributes': {'name': 'polygon',
      'x_values': [211, 205, 214, 232, 254, 263, 265, 265, 263, 257, 221],
      'y_values': [186, 200, 214, 218, 214, 204, 198, 190, 187, 181, 180]},
      'type': {'animal': '1'}},
      {'shape_attributes': {'name': 'polygon',
      'x_values': [272, 266, 275, 293, 315, 324, 326, 326, 324, 318, 282],
      'y_values': [233, 247, 261, 265, 261, 251, 245, 237, 234, 228, 227]},
      'type': {'animal': '2'}},
      {'shape_attributes': {'name': 'polygon',
      'x_values': [366, 360, 369, 387, 409, 418, 420, 420, 418, 412, 376],
      'y_values': [315, 329, 343, 347, 343, 333, 327, 319, 316, 310, 309]},
      'type': {'animal': '2'}},
      {'shape_attributes': {'name': 'polygon',
      'x_values': [201, 195, 204, 222, 244, 253, 255, 255, 253, 247, 211],
      'y_values': [224, 238, 252, 256, 252, 242, 236, 228, 225, 219, 218]},
      'type': {'animal': '3'}}],
      'file_attributes': {}}}

Я хочу проверить, больше ли 500 значений x_values ​​или y_values. Если оно больше 500 Я должен удалить его из словаря. Например, предположим, что

    {'shape_attributes': {'name': 'polygon',
    'x_values': [366, 360, 369, 387, 409, 418, 420, 420, 418, 412, 376],
    'y_values': [315, 329, 343, 347, 343, 333, 327, 319, 316, 310, 309]},
    'type': {'animal': '2'}}`

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

Может кто-нибудь мне помочь! Спасибо !!

Ответы [ 3 ]

1 голос
/ 06 апреля 2020

Это решение рекурсивно спускается вниз по пройденному объекту. Когда объект является списком, он рекурсивно спускается вниз по каждому элементу списка, и если сообщается, что искомый элемент был найден, он удаляется из списка. Когда объект является словарем, он проверяется на наличие ключа shape_attributes. Если это так, то проводится дальнейшее тестирование, чтобы увидеть, следует ли удалить этот словарь из родительского списка, и он должен вернуть True. В противном случае мы рекурсивно спускаемся вниз по значениям словаря.

from itertools import chain

def search_and_remove(o):
    if isinstance(o, list):
        for i, x in enumerate(o):
            if search_and_remove(x):
                del o[i]
        return False
    elif isinstance(o, dict):
        if 'shape_attributes' in o:
            d = o['shape_attributes']
            return any(map(lambda n: n > 500, chain(d['x_values'], d['y_values'])))
        else:
            for v in o.values():
                search_and_remove(v)
            return False

d =   {'pic1': {'filename': 'pic1.png',
      'size': 545,
      'regions': [{'shape_attributes': {'name': 'polygon',
      'x_values': [211, 205, 214, 232, 254, 263, 265, 265, 263, 257, 221],
      'y_values': [186, 200, 214, 218, 214, 204, 198, 190, 187, 181, 180]},
      'type': {'animal': '1'}},
      {'shape_attributes': {'name': 'polygon',
      'x_values': [272, 266, 275, 293, 315, 324, 326, 326, 324, 318, 282],
      'y_values': [233, 247, 261, 265, 261, 251, 245, 237, 234, 228, 227]},
      'type': {'animal': '2'}},
      {'shape_attributes': {'name': 'polygon',
      'x_values': [366, 360, 369, 387, 409, 418, 420, 420, 418, 412, 376],
      'y_values': [315, 329, 343, 347, 343, 333, 327, 319, 316, 310, 309]},
      'type': {'animal': '2'}},
      {'shape_attributes': {'name': 'polygon',
      'x_values': [201, 195, 204, 222, 244, 253, 255, 255, 253, 247, 211],
      'y_values': [224, 238, 252, 256, 252, 242, 236, 228, 225, 219, 218]},
      'type': {'animal': '3'}}],
      'file_attributes': {}},
      'pic2': {'filename': 'pic2.png',
      'size': 456,
      'regions': [{'shape_attributes': {'name': 'polygon',
      'x_values': [211, 205, 214, 232, 254, 263, 265, 265, 263, 257, 221],
      'y_values': [186, 200, 214, 218, 214, 204, 198, 190, 187, 181, 180]},
      'type': {'animal': '1'}},
      {'shape_attributes': {'name': 'polygon',
      'x_values': [272, 266, 275, 293, 315, 324, 326, 326, 324, 318, 282],
      'y_values': [233, 247, 261, 265, 261, 251, 245, 237, 234, 228, 227]},
      'type': {'animal': '2'}},
      {'shape_attributes': {'name': 'polygon',
      'x_values': [366, 360, 369, 387, 409, 418, 420, 420, 418, 412, 376],
      'y_values': [315, 329, 343, 347, 343, 333, 327, 319, 316, 310, 309]},
      'type': {'animal': '2'}},
      {'shape_attributes': {'name': 'polygon',
      'x_values': [201, 195, 204, 222, 244, 253, 255, 255, 253, 247, 211],
      'y_values': [224, 238, 252, 256, 252, 242, 236, 228, 225, 219, 218]},
      'type': {'animal': '3'}}],
      'file_attributes': {}}}

search_and_remove(d)
print(d)
1 голос
/ 06 апреля 2020

Это будет работать:

for key in dict1.keys():
    dict1[key]['regions'] = [value for value in dict1[key]['regions'] if
                               (max(value['shape_attributes']['x_values'])<=500)
                               and (max(value['shape_attributes']['y_values'])<=500)]

Поскольку у вас нет значения больше 500, ничего не будет отсортировано.

0 голосов
/ 06 апреля 2020

Вы можете использовать рекурсию:

data = {'pic1': {'filename': 'pic1.png', 'size': 545, 'regions': [{'shape_attributes': {'name': 'polygon', 'x_values': [211, 205, 214, 232, 254, 263, 265, 265, 263, 257, 221], 'y_values': [186, 200, 214, 218, 214, 204, 198, 190, 187, 181, 180]}, 'type': {'animal': '1'}}, {'shape_attributes': {'name': 'polygon', 'x_values': [272, 266, 275, 293, 315, 324, 326, 326, 324, 318, 282], 'y_values': [233, 247, 261, 265, 261, 251, 245, 237, 234, 228, 227]}, 'type': {'animal': '2'}}, {'shape_attributes': {'name': 'polygon', 'x_values': [366, 360, 369, 387, 409, 418, 420, 420, 418, 412, 376], 'y_values': [315, 329, 343, 347, 343, 333, 327, 319, 316, 310, 309]}, 'type': {'animal': '2'}}, {'shape_attributes': {'name': 'polygon', 'x_values': [201, 195, 204, 222, 244, 253, 255, 255, 253, 247, 211], 'y_values': [224, 238, 252, 256, 252, 242, 236, 228, 225, 219, 218]}, 'type': {'animal': '3'}}], 'file_attributes': {}}, 'pic2': {'filename': 'pic2.png', 'size': 456, 'regions': [{'shape_attributes': {'name': 'polygon', 'x_values': [211, 205, 214, 232, 254, 263, 265, 265, 263, 257, 221], 'y_values': [186, 200, 214, 218, 214, 204, 198, 190, 187, 181, 180]}, 'type': {'animal': '1'}}, {'shape_attributes': {'name': 'polygon', 'x_values': [272, 266, 275, 293, 315, 324, 326, 326, 324, 318, 282], 'y_values': [233, 247, 261, 265, 261, 251, 245, 237, 234, 228, 227]}, 'type': {'animal': '2'}}, {'shape_attributes': {'name': 'polygon', 'x_values': [366, 360, 369, 387, 409, 418, 420, 420, 418, 412, 376], 'y_values': [315, 329, 343, 347, 343, 333, 327, 319, 316, 310, 309]}, 'type': {'animal': '2'}}, {'shape_attributes': {'name': 'polygon', 'x_values': [201, 195, 204, 222, 244, 253, 255, 255, 253, 247, 211], 'y_values': [224, 238, 252, 256, 252, 242, 236, 228, 225, 219, 218]}, 'type': {'animal': '3'}}], 'file_attributes': {}}}
def valid(v):
  return not isinstance(v, list) or all(i < 500 for i in v if not isinstance(i, (dict, list)))

def r_dict(d):
  if isinstance(d, list):
     return [r_dict(i) if isinstance(i, dict) else i for i in d]
  return {a:r_dict(b) if isinstance(b, dict) else b for a, b in d.items() if valid(b)}

result = r_dict(data)

Вывод:

{'pic1': {'filename': 'pic1.png', 'size': 545, 'regions': [{'shape_attributes': {'name': 'polygon', 'x_values': [211, 205, 214, 232, 254, 263, 265, 265, 263, 257, 221], 'y_values': [186, 200, 214, 218, 214, 204, 198, 190, 187, 181, 180]}, 'type': {'animal': '1'}}, {'shape_attributes': {'name': 'polygon', 'x_values': [272, 266, 275, 293, 315, 324, 326, 326, 324, 318, 282], 'y_values': [233, 247, 261, 265, 261, 251, 245, 237, 234, 228, 227]}, 'type': {'animal': '2'}}, {'shape_attributes': {'name': 'polygon', 'x_values': [366, 360, 369, 387, 409, 418, 420, 420, 418, 412, 376], 'y_values': [315, 329, 343, 347, 343, 333, 327, 319, 316, 310, 309]}, 'type': {'animal': '2'}}, {'shape_attributes': {'name': 'polygon', 'x_values': [201, 195, 204, 222, 244, 253, 255, 255, 253, 247, 211], 'y_values': [224, 238, 252, 256, 252, 242, 236, 228, 225, 219, 218]}, 'type': {'animal': '3'}}], 'file_attributes': {}}, 'pic2': {'filename': 'pic2.png', 'size': 456, 'regions': [{'shape_attributes': {'name': 'polygon', 'x_values': [211, 205, 214, 232, 254, 263, 265, 265, 263, 257, 221], 'y_values': [186, 200, 214, 218, 214, 204, 198, 190, 187, 181, 180]}, 'type': {'animal': '1'}}, {'shape_attributes': {'name': 'polygon', 'x_values': [272, 266, 275, 293, 315, 324, 326, 326, 324, 318, 282], 'y_values': [233, 247, 261, 265, 261, 251, 245, 237, 234, 228, 227]}, 'type': {'animal': '2'}}, {'shape_attributes': {'name': 'polygon', 'x_values': [366, 360, 369, 387, 409, 418, 420, 420, 418, 412, 376], 'y_values': [315, 329, 343, 347, 343, 333, 327, 319, 316, 310, 309]}, 'type': {'animal': '2'}}, {'shape_attributes': {'name': 'polygon', 'x_values': [201, 195, 204, 222, 244, 253, 255, 255, 253, 247, 211], 'y_values': [224, 238, 252, 256, 252, 242, 236, 228, 225, 219, 218]}, 'type': {'animal': '3'}}], 'file_attributes': {}}}
...