【问题标题】:python: Convert a for loop into a recursion functionpython:将for循环转换为递归函数
【发布时间】:2014-01-10 16:40:29
【问题描述】:

首先,我还是 python 的新手,所以请放轻松。

我已经完成了我的研究,并且对如何编写递归函数有了基本的了解,但是我对摆在我面前的任务完全感到困惑。

我真的很想得到一些提示和指示,这样我就可以自己做这件事来真正理解。

这是任务:

  1. 遍历字典
  2. 检查是否有“儿童”键
  3. 如果是真的,做点什么
  4. 重复

问题来了,

“option”键嵌套在另一个名为“children”的键中。在那里,我想遍历每个“子”键,直到它们不再存在。

这是没有递归的代码的样子。当然它失败了,因为它太解释了,太死板了。

#level(one/two/three) refer to the level of nesting, easier for me to know where I am     in the loop.
#qdf_v2 is a particular type of file which is essentially a dictionary 

for levelone in qdf_v2['children']:
    if 'children' in levelone:
        store = options
        for leveltwo in levelone['children']:
            if 'children' in leveltwo:
                store = options
                for levelthree in leveltwo['children']:
                    if 'children' in levellevel:
                        repeat....

我想遍历字典,它是“儿童”键,直到它们不再存在。

这里有一些 JSON,您可以复制并粘贴到 http://www.jsoneditoronline.org/ 中以查看我正在处理的内容。

{
    "base": "http://panoptic-fearless.ldc.yougov.net/questionnaires/Test_maj_demo_newG4_2/versions/12/",
    "children": [
        {
            "name": "one",
            "children": [
                {
                    "name": "measures",
                    "children": [
                        {
                            "type": "single",
                            "options": {
                                "sort_order": "asending",
                                "chart_layout": "5",
                                "chart_type": "bar",
                                "chart_color": "green"
                            },
                            "text": "How much would you say you like or dislike P.E. at school? ",
                            "name": "KYS_Q1",
                            "responses": {
                                "items": [
                                    {
                                        "code": 1,
                                        "text": "I love it",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 2,
                                        "text": "I like it",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 3,
                                        "text": "I don’t like it",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 4,
                                        "text": "I hate it",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 5,
                                        "text": "Don’t know",
                                        "element": "qdf:response"
                                    }
                                ],
                                "element": "qdf:response_group"
                            },
                            "element": "qdf:question",
                            "export": [
                                {
                                    "name": "KYS_Q1"
                                }
                            ]
                        },
                        {
                            "children": [
                                {
                                    "type": "single",
                                    "options": {
                                        "sort_order": "asending",
                                        "chart_layout": "4",
                                        "chart_type": "pie",
                                        "chart_color": "pink"
                                    },
                                    "text": "{multiple order=\"randomize\" max=3} You said that you $event P.E. at school...<br/> Which THREE of the following are your MAIN reasons for not liking P.E. at school? (Please tick up to three options)",
                                    "name": "KYS_Q2",
                                    "responses": {
                                        "items": [
                                            {
                                                "code": 1,
                                                "text": "I don't like going outside in bad weather (e.g. in the cold, rain etc.)",
                                                "element": "qdf:response"
                                            },
                                            {
                                                "code": 2,
                                                "text": "I’m always picked last to join a team",
                                                "element": "qdf:response"
                                            },
                                            {
                                                "code": 3,
                                                "text": "I don't like my P.E. teacher/ don’t think they are very good",
                                                "element": "qdf:response"
                                            },
                                            {
                                                "code": 4,
                                                "text": "I’m not very good at it",
                                                "element": "qdf:response"
                                            },
                                            {
                                                "code": 5,
                                                "text": "I find the games/ sports we play boring",
                                                "element": "qdf:response"
                                            }
                                        ],
                                        "element": "qdf:response_group"
                                    },
                                    "element": "qdf:question",
                                    "export": [
                                        {
                                            "name": "KYS_Q2"
                                        }
                                    ]
                                },
                                {
                                    "type": "single",
                                    "options": {
                                        "sort_order": "asending",
                                        "chart_layout": "5",
                                        "chart_type": "line",
                                        "chart_color": "green"
                                    },
                                    "text": "{multiple order=\"randomize\"} Below are some feelings that people can have about doing P.E. at school...<br/> Which of the following words describe how you feel about doing P.E. at school? (Please tick all that apply) ",
                                    "name": "KYS_Q3A",
                                    "responses": {
                                        "items": [
                                            {
                                                "code": 1,
                                                "text": "Stressed",
                                                "element": "qdf:response"
                                            },
                                            {
                                                "code": 2,
                                                "text": "Scared",
                                                "element": "qdf:response"
                                            },
                                            {
                                                "code": 3,
                                                "text": "Worried",
                                                "element": "qdf:response"
                                            },
                                            {
                                                "code": 4,
                                                "text": "Sick",
                                                "element": "qdf:response"
                                            },
                                            {
                                                "code": 5,
                                                "text": "Tiring ",
                                                "element": "qdf:response"
                                            }
                                        ],
                                        "element": "qdf:response_group"
                                    },
                                    "element": "qdf:question",
                                    "export": [
                                        {
                                            "name": "KYS_Q3A"
                                        }
                                    ]
                                }
                            ],
                            "element": "qdf:section"
                        },
                        {
                            "type": "single",
                            "options": {
                                "sort_order": "desending",
                                "chart_layout": "5",
                                "chart_type": "bar",
                                "chart_color": "green"
                            },
                            "text": "{single order=\"randomize\"} You said that you $event P.E...<br/> Which ONE of the following is the main reason you like it? ",
                            "name": "KYS_Q4",
                            "responses": {
                                "items": [
                                    {
                                        "code": 1,
                                        "text": "I like getting outside/ not being in the classroom",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 2,
                                        "text": "I like my P.E. teacher",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 3,
                                        "text": "I’m good at it",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 4,
                                        "text": "I find the games/ sports fun",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 5,
                                        "text": "I find the games/ sports easy",
                                        "element": "qdf:response"
                                    }
                                ],
                                "element": "qdf:response_group"
                            },
                            "element": "qdf:question",
                            "export": [
                                {
                                    "name": "KYS_Q4"
                                }
                            ]
                        }
                    ],
                    "element": "qdf:page"
                }
            ],
            "element": "qdf:module"
        },
        {
            "name": "two",
            "children": [
                {
                    "name": "test",
                    "children": [
                        {
                            "type": "single",
                            "options": {
                                "sort_order": "asending",
                                "chart_layout": "5",
                                "chart_type": "bar",
                                "chart_color": "green"
                            },
                            "text": "{multiple order=\"randomize\"}Below are some feelings that people can have about doing P.E at school...<br/> Which of the following words describe how you feel about doing P.E. at school? (Please tick all that apply)   ",
                            "name": "KYS_Q5A",
                            "responses": {
                                "items": [
                                    {
                                        "code": 1,
                                        "text": "Energised/ Awake",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 2,
                                        "text": "Excited",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 3,
                                        "text": "Relaxed",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 4,
                                        "text": "Confident",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 5,
                                        "text": "Happy",
                                        "element": "qdf:response"
                                    }
                                ],
                                "element": "qdf:response_group"
                            },
                            "element": "qdf:question",
                            "export": [
                                {
                                    "name": "KYS_Q5A"
                                }
                            ]
                        },
                        {
                            "type": "single",
                            "options": {
                                "sort_order": "asending",
                                "chart_layout": "25",
                                "chart_type": "column",
                                "chart_color": "orange"
                            },
                            "text": "{multiple order=\"randomize\"} For the following question please do not be afraid to be as honest as possible, no one else will be told your personal answers. <br/> Which of the following have you EVER done in order to avoid taking part in P.E. at school? (Please tick all that apply) ",
                            "name": "KYS_Q6",
                            "responses": {
                                "items": [
                                    {
                                        "code": 1,
                                        "text": "Lied about forgetting my kit",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 2,
                                        "text": "Lied about an injury",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 3,
                                        "text": "Lied about feeling unwell",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 4,
                                        "text": "Faked a note from my parents/ guardian",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 5,
                                        "text": "Faked a note from my doctor/ health professional",
                                        "element": "qdf:response"
                                    }
                                ],
                                "element": "qdf:response_group"
                            },
                            "element": "qdf:question",
                            "export": [
                                {
                                    "name": "KYS_Q6"
                                }
                            ]
                        },
                        {
                            "type": "single",
                            "options": {
                                "sort_order": "asending",
                                "chart_layout": "5",
                                "chart_type": "bar",
                                "chart_color": "green"
                            },
                            "text": "{multiple order=\"randomize\"} For the following question, please think about the teacher who has taught you P.E. MOST recently and if you have more than one teacher teaching you P.E. please think about the one who has taught you most often. <br/>  Which of the following statements do you agree with? (Please tick all that apply)",
                            "name": "KYS_Q7",
                            "responses": {
                                "items": [
                                    {
                                        "code": 1,
                                        "text": "My P.E. teacher inspires me to do more exercise",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 2,
                                        "text": "My P.E. teacher motivates me to take part in P.E. lessons",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 3,
                                        "text": "My P.E. teacher scares me",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 4,
                                        "text": "My P.E. teacher makes P.E. boring",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 5,
                                        "text": "My P.E. teacher makes P.E. fun",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 6,
                                        "text": "My P.E. teacher makes P.E. difficult/ hard",
                                        "element": "qdf:response"
                                    }
                                ],
                                "element": "qdf:response_group"
                            },
                            "element": "qdf:question",
                            "export": [
                                {
                                    "name": "KYS_Q7"
                                }
                            ]
                        },
                        {
                            "type": "single",
                            "options": {
                                "sort_order": "asending",
                                "chart_layout": "5",
                                "chart_type": "bar",
                                "chart_color": "green"
                            },
                            "text": "{multiple order=\"randomize\"} What would make you like P.E. more? (Please tick all that apply)",
                            "name": "KYS_Q8",
                            "responses": {
                                "items": [
                                    {
                                        "code": 1,
                                        "text": "If the P.E. teacher was nicer to me",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 2,
                                        "text": "If more lessons took place indoors (e.g. in the sports hall or a gym)",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 3,
                                        "text": "If more lessons took place outdoors",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 4,
                                        "text": "If we did more interesting sports/ activities",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 5,
                                        "text": "If we had more choice of the types of sport we had to do",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "code": 6,
                                        "text": "If we could wear what we wanted for the lesson",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "options": {
                                            "fixed": true
                                        },
                                        "children": [
                                            {
                                                "export": [
                                                    {
                                                        "name": "KYS_Q8other"
                                                    }
                                                ],
                                                "name": "KYS_Q8other",
                                                "type": "open",
                                                "element": "qdf:question"
                                            }
                                        ],
                                        "code": 7,
                                        "text": "Other ",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "options": {
                                            "xor": true,
                                            "fixed": true
                                        },
                                        "code": 8,
                                        "text": "Don’t know",
                                        "element": "qdf:response"
                                    },
                                    {
                                        "options": {
                                            "xor": true,
                                            "fixed": true
                                        },
                                        "code": 9,
                                        "text": "Not applicable – nothing would make me like P.E. more than I already do",
                                        "element": "qdf:response"
                                    }
                                ],
                                "element": "qdf:response_group"
                            },
                            "element": "qdf:question",
                            "export": [
                                {
                                    "name": "KYS_Q8"
                                }
                            ]
                        }
                    ],
                    "element": "qdf:page"
                }
            ],
            "element": "qdf:module"
        },
        {
            "children": [
                {
                    "children": [
                        {
                            "text": "​\n",
                            "element": "qdf:text"
                        }
                    ],
                    "element": "qdf:page"
                }
            ],
            "element": "qdf:module"
        }
    ],
    "panelid": 13,
    "created": "#2014-01-10T15:57:18.594000+00:00#",
    "typespec": {
        "src": "/questionnaires/typespecs/initial.qdf",
        "element": "qdf:typespec"
    },
    "qdf-ext:ext": [
        "meaningful-page-names"
    ],
    "element": "qdf:questionnaire",
    "builtin": {
        "src": "/questionnaires/builtins/initial.qdf",
        "element": "qdf:typedef"
    },
    "committer": "majeed.sahebzadha",
    "name": "Test_maj_demo_newG4_2",
    "commit message": "added a new module within a module"
}

【问题讨论】:

  • 你能分享一个示例字典吗?
  • 还有预期的输出?
  • 输出显示有点困难。但基本上我将“option”键的值存储在“children”键中,并通过函数将其发送到另一个文件。但我只需要了解如何重复这个过程。

标签: python for-loop recursion


【解决方案1】:

我会这样处理:

def recursive(input, output=None):
    if output is None:
        output = {} # container to store results
    if 'children' in input:
        # do whatever, add things to output
        recursive(input['children'], output)
    return output

这样,output 字典可以在所有迭代深度中访问,并在最后获得带有所有内容的 returned。这意味着您不必显式处理递归调用的 return 值。

根据您所拥有的具体情况,它可能看起来更像:

def recursive(input, output=None):
    if output is None:
        output = {} # container to store results
    if 'children' in input:
        for child in input['children']:
            # do whatever, add things to output
            recursive(child, output)
    return output    

output 可能是不同的容器(例如listset)。

【讨论】:

  • 这会在输出中添加任何内容吗?我很困惑。
  • @adsmith:因为我们不知道 OP 想要输出什么,所以这个答案留待填写。
  • 我的示例没有明确添加任何内容,但是我不知道 OP 想要提取什么!关键是所有递归调用都共享同一个对象,因此您可以将所有结果收集在一起。
  • 由于 OP 回复解释说他想要每个递归中另一个键的值,因此这是首选实现。
【解决方案2】:
def recurseDict(dictionary):
    if "children" in dictionary:
        return recurseDict(dictionary['children'])
    else:
        return "Whatever you want to return here -- you didn't specify"

这将获取一个字典,检查 "children" 是否是它的键之一,然后递归遍历字典 dictionary['children'] 等等,直到它到达没有 'children' 键的地步(例如字典没有更多的分支)它进入else 分支,你可以返回任何你想要的东西——你没有指定。

【讨论】:

  • -1 -- if "children" in dictionary.keys() 这绝对是检查某个键是否在字典中的错误方法。
  • @MartijnPieters 哎呀!我对自递归函数很生疏。他们从不觉得我是正确的答案。 @Bakurio:改为if 'children' in dictionary——我不记得我是否可以这样做,所以我倾向于默认构建一个键列表并检查它。
  • @Bakuriu 我想我可以做 try: return recurseDict(dictionary['children']) except KeyError: return "whatever OP wants" 如果你认为那会更 Pythonic。
  • 不,你没有抓住重点。检查一个键是否字典中的正确方法是用英文写它:key in dictionary没有调用.keys()
【解决方案3】:

这是一个递归遍历字典的示例方法,假设每个孩子也是一个字典:

def compute(my_dict):
    if 'children' in my_dict:
        print my_dict['children']
        for child in my_dict['children']:
            compute(child)

【讨论】:

  • if 'children' in my_dict 将失败,如果 my_dict 不是可迭代的,print my_dict['children'] 将失败,如果 my_dict 不是 dict-like。您需要检查对象的类型(使用 is_instance)或将这些表达式放在 try ... except 块中。我更喜欢鸭式打字,即使用 try ... except。
  • @SteinarLima 如果此函数未向用户公开,则没有理由期望将 dict 传递给它。如果你非常担心它,你可以将def compute 的第一行写成assert typeof(my_dict) == dict,如果你给了它无法处理的任何东西,它会立即抛出AssertionError
  • my_dict = {'children': ['children', 'of', 'men']} 怎么样。这是一个递归函数,所以最初的 my_dict 是一个字典是不够的,所有子项也需要是一个字典。
  • 是的,数据结构应该是这样设计的。当 children 键存在时,它应该包含子节点,而不是值。只应在需要时使用鸭子打字。例如,对于外部数据结构,这可能是必要的,但如果您设计数据结构,那么为关键子级混合不同级别的子节点和值是没有意义的。
猜你喜欢
  • 2013-05-31
  • 2018-03-15
  • 2019-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-20
相关资源
最近更新 更多