2015-03-04 4 views
1

Я хочу сделать глубокую копию структуры данных python, игнорируя некоторые элементы, основанные на некоторых критериях.глубокая копия с фильтрацией в python

Например, вход может быть произвольным json, и я бы хотел скопировать все , но словари с ключом «игнорировать». Как это:

def my_filter(entry): 
    # return true if we need to skip this entry 
    if not isinstance(entry, dict): return False 
    return ('ignore' in entry) 

a = [ 
    {"free": "yourself", "ignore": ""}, 
    [ 
     {"two": "words" }, 
     {"one": "finger"}, 
     [{"apples": 2}, {"array": [1,2,3,4], "ignore": ""}], 
    ], 
    {"hi": "there", "ignore": ""}, 
] 

print copy_with_filter(a, my_filter) 

и было бы выход

[[{'two': 'words'}, {'one': 'finger'}, [{'apples': 2}]]] 

Я реализовал этот код, который делает работу для ввода JSon, то есть когда только список, ДИКТ или литералы могут присутствовать и он хорошо работает:

def copy_with_filter(a, filter_func): 
    # assume input is either list, or dict, or "literal" (i.e. string/int/float) 
    if isinstance(a, list): 
     out = [ copy_with_filter(x, filter_func) for x in a if not filter_func(x) ] 
    elif isinstance(a, dict): 
     out = a.copy() # shallow copy first 
     for k in a.iterkeys(): 
      # replace values with filtered deep copies 
      out[k] = copy_with_filter(a[k], filter_func) 
    else: 
     out = a 
    return out 

Хотя мой вопрос, есть ли более общий/лучше/встроенный способ сделать глубокую копию с фильтрацией в Python?

ответ

1

Использование встроенного в Python встроенного модуля памяти с memoization - это работает лучше при глубоком копировании структуры с ресурсами с перекрестными ссылками - ваш подход будет создавать дубликаты вещей, которые многократно ссылаются на дочерние объекты корневого объекта.

Питон документация несколько ужасны:

https://docs.python.org/2/library/copy.html

... но есть хорошие учебники там. Один SO размещают на перегрузку конструкторов копирования для пользовательских классов:

Python: Implementation of shallow and deep copy constructors

Добавления фильтрации является немного более неудобным - но для пользовательских объектов этого достаточно (легко просто рано из DeepCopy конструктора по без добавления новый объект для memo dict - единственная реальная трудность - это сантехника в пользовательских правилах фильтрации, но это просто сантехника).

Смежные вопросы