使用嵌套列表

时间:2015-07-21 22:54:17

标签: python json forms dictionary flask

鉴于从网络表单收到以下数据:

for key in request.form.keys():
    print key, request.form.getlist(key)

group_name [u'myGroup']
category [u'social group']
creation_date [u'03/07/2013']
notes [u'Here are some notes about the group']
members[0][name] [u'Adam']
members[0][location] [u'London']
members[0][dob] [u'01/01/1981']
members[1][name] [u'Bruce']
members[1][location] [u'Cardiff']
members[1][dob] [u'02/02/1982']

如何将其变成这样的字典?它最终将被用作JSON,但由于JSON和字典很容易互换,我的目标只是达到以下结构。

event = {
    group_name : 'myGroup',
    notes : 'Here are some notes about the group,
    category : 'social group',
    creation_date : '03/07/2013',
    members : [
        {
            name : 'Adam',
            location : 'London',
            dob : '01/01/1981'
        }
        {
            name : 'Bruce',
            location : 'Cardiff',
            dob : '02/02/1982'
        }
    ]
}

这是我迄今为止所管理的内容。使用以下列表理解我可以轻松理解普通字段:

event = [ (key, request.form.getlist(key)[0]) for key in request.form.keys() if key[0:7] != "catches" ]

但是我在成员名单上苦苦挣扎。可以有任意数量的成员。我想我需要为它们单独创建一个列表,并将其添加到具有非迭代记录的字典中。我可以像这样得到会员数据:

tmp_members = [(key, request.form.getlist(key)) for key in request.form.keys() if key[0:7]=="members"]

然后我可以提取列表索引和字段名称:

member_arr = []
members_orig = [ (key, request.form.getlist(key)[0]) for key in request.form.keys() if key[0:7] == 

"members" ]
for i in members_orig:
    p1 = i[0].index('[')
    p2 = i[0].index(']')
    members_index = i[0][p1+1:p2]
    p1 = i[0].rfind('[')
    members_field = i[0][p1+1:-1]

但是如何将其添加到我的数据结构中。以下操作无效,因为我可能会尝试在members[1][name]之前处理members[0][name]

members_arr[int(members_index)] = {members_field : i[1]}

这看起来很复杂。有没有更简单的方法来做到这一点,如果不是,我怎么能让这个工作?

3 个答案:

答案 0 :(得分:1)

您可以将数据存储在字典中,然后使用json库。

import json
json_data = json.dumps(dict)
print(json_data)

这将打印一个json字符串。

查看json library here

答案 1 :(得分:0)

是的,将它转换为字典,然后使用带有一些可选参数的json.dumps()以您需要的格式打印出JSON:

eventdict = {
    'group_name': 'myGroup',
    'notes': 'Here are some notes about the group',
    'category': 'social group',
    'creation_date': '03/07/2013',
    'members': [
        {'name': 'Adam',
         'location': 'London',
         'dob': '01/01/1981'},
        {'name': 'Bruce',
         'location': 'Cardiff',
         'dob': '02/02/1982'}
        ]
    }

import json

print json.dumps(eventdict, indent=4)

key:value对的顺序并不总是一致的,但是如果你只是寻找可以由脚本解析的漂亮的JSON,同时保持人类可读,这应该可行。您还可以使用以下字母顺序对键进行排序:

print json.dumps(eventdict, indent=4, sort_keys=True)

答案 2 :(得分:0)

以下python函数可用于从flat字典创建嵌套字典。只需将html表单输出传递给decode()。

def get_key_name(str):
    first_pos = str.find('[')
    return str[:first_pos]

def get_subkey_name(str):
    '''Used with lists of dictionaries only'''
    first_pos = str.rfind('[')
    last_pos = str.rfind(']')
    return str[first_pos:last_pos+1]

def get_key_index(str):
    first_pos = str.find('[')
    last_pos = str.find(']')
    return str[first_pos:last_pos+1]

def decode(idic):
    odic = {} # Initialise an empty dictionary
    # Scan all the top level keys
    for key in idic:
        # Nested entries have [] in their key
        if '[' in key and ']' in key:
            if key.rfind('[') == key.find('[') and key.rfind(']') == key.find(']'):
                print key, 'is a nested list'
                key_name = get_key_name(key)
                key_index = int(get_key_index(key).replace('[','',1).replace(']','',1))
                # Append can't be used because we may not get the list in the correct order.
                try:
                    odic[key_name][key_index] = idic[key][0]
                except KeyError: # List doesn't yet exist
                     odic[key_name] = [None] * (key_index + 1)
                     odic[key_name][key_index] = idic[key][0]
                except IndexError: # List is too short
                     odic[key_name] = odic[key_name] + ([None] * (key_index - len(odic[key_name]) + 1 ))
                     # TO DO: This could be a function
                     odic[key_name][key_index] = idic[key][0]
            else:
                key_name = get_key_name(key)
                key_index = int(get_key_index(key).replace('[','',1).replace(']','',1))
                subkey_name = get_subkey_name(key).replace('[','',1).replace(']','',1)
                try:
                    odic[key_name][key_index][subkey_name] = idic[key][0]
                except KeyError: # Dictionary doesn't yet exist
                    print "KeyError"
                    # The dictionaries must not be bound to the same object
                    odic[key_name] = [{} for _ in range(key_index+1)]
                    odic[key_name][key_index][subkey_name] = idic[key][0]
                except IndexError: # List is too short
                    # The dictionaries must not be bound to the same object
                    odic[key_name] = odic[key_name] + [{} for _ in range(key_index - len(odic[key_name]) + 1)]
                    odic[key_name][key_index][subkey_name] = idic[key][0]
        else:
            # This can be added to the output dictionary directly
            print key, 'is a simple key value pair'
            odic[key] = idic[key][0]
    return odic