在python中,如何将dict复制到特定深度?

2024-06-02 11:53:12 发布

您现在位置:Python中文网/ 问答频道 /正文

例如,如果我有dict的dict或数组的dict,但我只希望“深度”复制到两个级别的深度,有没有一种简单的方法可以做到这一点?在

我环顾四周,想看看是否有我可以使用的图书馆或一个例子,但我找不到任何东西。我对Python相当陌生,否则我会自己编写子程序来完成这项工作。有什么想法吗?代码片段将是感激的,因为它将使我更快地理解,而不仅仅是一个如何做的解释。在

谢谢。在

其他信息:

有人问我为什么要这样做,我需要一个副本(不是一个ref,因为我要修改一些值,我不希望原始的修改),但dict是巨大的(许多dict的dict),所以我不想炸毁我的内存占用

我目前的代码

好吧,我放弃。这比我预想的要困难,我没有时间去想。我最近尝试了一些调试/测试代码。在

# Deep copy any iteratable item to a max depth and defaults to removing the
# rest. If you want to keep the stuff past max depth as references to orig
# pass the argument else_ref=1. Ex:
#   dict_copy = copy_to_depth( dict_orig, 2, else_ref=1 )
def copy_to_depth( orig, depth, **kwargs):
  copy = type(orig)()
  for key in orig:
    # Cannot find a reliable and consistent way to determine if the item 
    # is iterable.
    #print orig[key].__class__
    #if hasattr(orig[key], '__iter__'):
    #if hasattr(orig[key], '__contains__'):
    #if iterable( orig[key] ):
    #try:
    if hasattr(orig[key], '__contains__'):
      if depth > 0:
        copy[key] = copy_to_depth(orig[key], depth - 1, **kwargs)
      else:
        if 'else_ref' in kwargs:
          copy[key] = orig[key]
        else:
          copy[key] = 'PAST_MAX_DPETH_ITERABLE_REMOVED'
    #except:
    else:
      copy[key] = orig[key]
  return copy

def iterable(a):
   try:
       (x for x in a)
       return True
   except TypeError:
       return False

people = {'rebecca': 34, 'dave': 'NA', 'john': 18, 'arr': [9,8,{'a':1,'b':[1,2]}], 'lvl1':
  {'arr': [9,8,{'a':1,'b':[1,2]}], 'dave': 'NA', 'john': 18, 'rebecca': 34, 'lvl2':
    {'arr': [9,8,{'a':1,'b':[1,2]}], 'dave': 'NA', 'john': 18, 'rebecca': 34, 'lvl3':
      {'rebecca': 34, 'dave': 'NA', 'john': 18, 'arr': [9,8,{'a':1,'b':[1,2]}]}}}}
print people


ppl_cpy = copy_to_depth(people, 1)

ppl_cpy['arr'][1] = 'nine'                  # does not mod orig
ppl_cpy['john'] = 0                  # does not mod orig
ppl_cpy['lvl1']['john'] = 1          # does not mod orig b/c copy_to_depth
ppl_cpy['arr'][3]['a'] = 'aie'       # does not mod orig
#ppl_cpy['lvl1']['lvl2']['john'] = 2 # Rest cause an error
#ppl_cpy['lvl1']['lvl2']['lvl3']['john'] = 3
print people
print ppl_cpy

ppl_cpy = copy_to_depth(people, 1, else_ref=1)
ppl_cpy['john'] = 0                 # does not mod orig
ppl_cpy['lvl1']['john'] = 1         # does not mod orig b/c copy_to_depth was 1
ppl_cpy['lvl1']['lvl2']['john'] = 2 # Rest Do not cause error but modifies orig
ppl_cpy['lvl1']['lvl2']['lvl3']['john'] = 3
print people
print ppl_cpy

我找不到一个可靠和一致的方法来确定这个项目是否可以接受。我一直在通读this post并试图找出它,但似乎没有一个解决方案适合我的测试用例。在

我将只是深入复制整个dict,并尝试优化解决方案稍后(或不)。在

谢谢。。。在


Tags: tokeyifnotjohnpeoplepplelse
2条回答

实际上,前面的例子只是复制任何字典,因为如果我们没有足够的深度,我们只直接复制剩下的部分。正确的版本是:

def copy_to_depth(original, depth)
    copy = type(original)()
    for item in original
        if item is iterable
            if depth > 0
                copy + copy_to_depth(item, depth - 1)
        else
            copy + item
    return copy

有一个微妙的区别。 (不幸的是,我无法对答案本身发表评论)

这听起来有点像“plz给我密码”。。。在

在任何情况下,除非您真的想用子类来破坏iterables的功能,否则您将需要一个自定义方法。伪代码:

def copy_to_depth(original, depth)
    copy = type(original)()
    for item in original
        if item is iterable and depth > 0
            copy + copy_to_depth(item, depth - 1)
        else
            copy + item
    return copy

相关问题 更多 >