【问题标题】:convert a dictionary recursively in Python在 Python 中递归地转换字典
【发布时间】:2018-02-21 05:02:49
【问题描述】:

这是一本字典:

data = {
    'a': {
        'b': {
            'c': {
                'd': {
                    'e': {
                        'f': 1,
                        'g': 50,
                        'h': [1, 2, 4],
                        'i': 3,
                        'j': [7, 9, 6],
                        'k': [
                            [('x', 'abc')],
                            [('y', 'qwe')],
                            [('z', 'zxc')]
                        ]
                    }
                }
            }
        }
    }
}

我的目标是尽可能找到值并将其转换为字典:

data = {
    'a': {
        'b': {
            'c': {
                'd': {
                    'e': {
                        'f': 1,
                        'g': 50,
                        'h': [1, 2, 4],
                        'i': 3,
                        'j': [7, 9, 6],
                        'k': [{
                            'x': 'abc'
                        }, {
                            'y': 'qwe'
                        }, {
                            'z': 'zxc'
                        }]
                    }
                }
            }
        }
    }
}

我认为这可以使用递归来完成,我什至写了一个,但它不起作用。

def f(d):
  for key, value in d.iteritems():
    if type(d[key]) is dict:
      f(d)

    try:
      d[key] = dict(d[key])
    except:
      if type(d[key]) is list:
        for i in d[key]:
          try:
            d[key][i] = dict(d[key][i])
          except:
            pass

  return d

错误:

RecursionError: 调用 Python 对象时超出最大递归深度

如何让它发挥作用?

如果你能提供一个没有递归的解决方案,我也会很高兴得到它。

【问题讨论】:

  • (只需在此处添加答案,因为它似乎只是代码中的错字)-您在第 4 行的递归:f(d) 一遍又一遍地调用相同的函数,而没有更改范围。您将遇到堆栈溢出。我想你的意思是f(d[key]),以便它在子字典上执行f()。 (不争辩这是一个离题/不好的问题)
  • @DanilSperansky:这个问题缺乏明确的问题陈述; 添加了错误信息。在那之前,这个问题是题外话。如果您想讨论关闭后的工作原理,可以通过Meta Stack Overflow 进行讨论。
  • @DanilSperansky:How soon should I "vote to close"?:总是投票立即关闭

标签: python dictionary recursion


【解决方案1】:

您的程序中有很多错误,让我们检查一下并提出一个工作版本。

def f(d):
  for key, value in d.iteritems():
    if type(d[key]) is dict:
      f(d)                        # You should call d[key] instead 
    try:
      d[key] = dict(d[key])       # Never assign an object back to the one you are iterating over, create a new object instead.
    except:
      if type(d[key]) is list:
        for i in d[key]:
          try:
            d[key][i] = dict(d[key][i])  # This doesn't work, can't convert a tuple/list this way.
          except:
            pass

  return d

这是您的代码的更正版本,其中包含两个递归函数。一个用于列表,另一个用于字典。

def f1(value):
  e = []
  for val in value:
    if type(val) is list:
      e += f1(val)               # Append list to current list
    elif type(val) is tuple:
      e.append({val[0]: val[1]}) # Convert tuple to dictionary
    else:
      e.append(val)              # Append normal list values normally
  return e

def f(d, e  = {}):
  for key, value in d.iteritems():
    if type(value) is dict:
      e[key] = f(value, {})     # Recurse for dictionaries
    elif type(value) is list:
      e[key] = f1(value)        # Call the other recursive function for list
    else:
      e[key] = value            # Otherwise like strings and ints just append
  return e

在这里测试:https://repl.it/LDKn/0

【讨论】:

    【解决方案2】:

    如果它是字典,则在 d 而不是 value 上递归调用该函数。

    只需将其更改为:

    if type(value) is dict:
        f(value)
    

    【讨论】:

      猜你喜欢
      • 2010-11-05
      • 1970-01-01
      • 1970-01-01
      • 2018-10-04
      • 2020-07-09
      • 2013-09-27
      • 1970-01-01
      • 2013-01-15
      • 2012-07-26
      相关资源
      最近更新 更多