Python 将目录列表转换为更便于下拉的格式

Python 将目录列表转换为更便于下拉的格式,python,Python,我试图为多个相关的HTML下拉列表创建一个友好的格式 如何转换字典d,使其看起来像字典输出 d = [ {"state": "California", "county": "Monterey", "city": "Salinas"}, {"state": "California", "county": "Monterey", "city": "Gonzales"}, {"state": "Oregon", "county": "Douglas", "city": "Ros

我试图为多个相关的HTML下拉列表创建一个友好的格式

如何转换字典
d
,使其看起来像字典
输出

d = [
    {"state": "California", "county": "Monterey", "city": "Salinas"},
    {"state": "California", "county": "Monterey", "city": "Gonzales"},
    {"state": "Oregon", "county": "Douglas", "city": "Roseburg"},
    {"state": "Oregon", "county": "Douglas", "city": "Winston"},
    {"state": "California", "county": "Alameda", "city": "Berkeley"},
]

output = {
    "California": {
        "Monterey": ["Salinas", "Gonzales"],
        "Alameda": ["Berkeley"],
    },
    "Oregon": {
        "Douglas": ["Roseburg", "Winston"],
    }
}

我不希望使用Pandas,只使用纯Python,因为我还需要将解决方案转换为JavaScript(尽管如此,我尝试了将
d
转换为数据帧,应用不同的方向,但没有一个方向提供了我想要的输出)。

您可以使用以下方法来完成此操作:

输出:

{'California': {'Monterey': ['Salinas', 'Gonzales'], 
                'Alameda': ['Berkeley']}, 
 'Oregon': {'Douglas': ['Roseburg', 'Winston']}}

如果您需要更快的速度,请查看每次创建默认对象时没有任何开销的方法:

您只需使用以下方法即可完成此操作:

输出:

{'California': {'Monterey': ['Salinas', 'Gonzales'], 
                'Alameda': ['Berkeley']}, 
 'Oregon': {'Douglas': ['Roseburg', 'Winston']}}

如果您需要更快的速度,请查看每次创建默认对象时没有开销的地方:

循环浏览列表并处理每个字典,将每个条目添加到输出中的适当位置,必要时创建新的字典和列表

d = [
    {"state": "California", "county": "Monterey", "city": "Salinas"},
    {"state": "California", "county": "Monterey", "city": "Gonzales"},
    {"state": "Oregon", "county": "Douglas", "city": "Roseburg"},
    {"state": "Oregon", "county": "Douglas", "city": "Winston"},
    {"state": "California", "county": "Alameda", "city": "Berkeley"},
]

output = {}

for place in d:
    if place['state'] not in output:
        output[place['state']] = {}
    if place['county'] not in output[place['state']]:
        output[place['state']][place['county']] = []
    output[place['state']][place['county']].append(place['city'])
结果:

>>> import pprint
>>> pprint.pprint(output, width=30)
{'California': {'Alameda': ['Berkeley'],
                'Monterey': ['Salinas',
                             'Gonzales']},
 'Oregon': {'Douglas': ['Roseburg',
                        'Winston']}}
或者,使用
集合。defaultdict

from collections import defaultdict as dd
output = dd(lambda: dd(list))
for place in d:
    output[place['state']][place['county']].append(place['city'])
结果是:

>>> pprint.pprint(output)
defaultdict(<function <lambda> at 0x000000E254B53E18>,
            {'California': defaultdict(<class 'list'>,
                                       {'Alameda': ['Berkeley'],
                                        'Monterey': ['Salinas', 'Gonzales']}),
             'Oregon': defaultdict(<class 'list'>,
                                   {'Douglas': ['Roseburg', 'Winston']})})
>>pprint.pprint(输出)
defaultdict(,
{'California':defaultdict(,
{'Alameda':['Berkeley'],
“蒙特利”:[萨利纳斯”,“冈萨雷斯],
“俄勒冈州”:defaultdict(,
{'Douglas':['Roseburg','Winston']})

循环浏览列表并处理每个词典,将每个条目添加到输出中的适当位置,必要时创建新词典和列表

d = [
    {"state": "California", "county": "Monterey", "city": "Salinas"},
    {"state": "California", "county": "Monterey", "city": "Gonzales"},
    {"state": "Oregon", "county": "Douglas", "city": "Roseburg"},
    {"state": "Oregon", "county": "Douglas", "city": "Winston"},
    {"state": "California", "county": "Alameda", "city": "Berkeley"},
]

output = {}

for place in d:
    if place['state'] not in output:
        output[place['state']] = {}
    if place['county'] not in output[place['state']]:
        output[place['state']][place['county']] = []
    output[place['state']][place['county']].append(place['city'])
结果:

>>> import pprint
>>> pprint.pprint(output, width=30)
{'California': {'Alameda': ['Berkeley'],
                'Monterey': ['Salinas',
                             'Gonzales']},
 'Oregon': {'Douglas': ['Roseburg',
                        'Winston']}}
或者,使用
集合。defaultdict

from collections import defaultdict as dd
output = dd(lambda: dd(list))
for place in d:
    output[place['state']][place['county']].append(place['city'])
结果是:

>>> pprint.pprint(output)
defaultdict(<function <lambda> at 0x000000E254B53E18>,
            {'California': defaultdict(<class 'list'>,
                                       {'Alameda': ['Berkeley'],
                                        'Monterey': ['Salinas', 'Gonzales']}),
             'Oregon': defaultdict(<class 'list'>,
                                   {'Douglas': ['Roseburg', 'Winston']})})
>>pprint.pprint(输出)
defaultdict(,
{'California':defaultdict(,
{'Alameda':['Berkeley'],
“蒙特利”:[萨利纳斯”,“冈萨雷斯],
“俄勒冈州”:defaultdict(,
{'Douglas':['Roseburg','Winston']})

这些是我一直喜欢使用的一些实用功能:

from collections import defaultdict

def group_by_key_func(iterable, key_func):
    result = defaultdict(list)
    for item in iterable:
        result[key_func(item)].append(item)
    return result

def group_by_key(iterable, key):
    return group_by_key_func(iterable, lambda x: x[key])
有了他们,答案就变成了:

output = {
    state: {
        county: [row['city'] for row in county_group]
        for county, county_group in group_by_key(state_group, 'county').items()
    }
    for state, state_group in group_by_key(d, 'state').items()
}

以下是我一直喜欢使用的一些实用功能:

from collections import defaultdict

def group_by_key_func(iterable, key_func):
    result = defaultdict(list)
    for item in iterable:
        result[key_func(item)].append(item)
    return result

def group_by_key(iterable, key):
    return group_by_key_func(iterable, lambda x: x[key])
有了他们,答案就变成了:

output = {
    state: {
        county: [row['city'] for row in county_group]
        for county, county_group in group_by_key(state_group, 'county').items()
    }
    for state, state_group in group_by_key(d, 'state').items()
}

这里有一个版本,它可以进行最少的
dict
查找(通过使用
dict.get
并检查
None
)和最少的空
dict
列表的创建(不使用类似于
dict.setdefault(…,[])
,其中可能的默认值总是被创建的)。对于数据的大小来说,这可能没有什么区别,但其他人比我先给出了我的原始答案,所以我认为这可能很好

def make_dropdown_data(items):
    data = {}
    for item in items:
        state = item['state']
        state_data = data.get(state)
        if state_data is None:
            data[state] = state_data = {}
        county = item['county']
        county_data = state_data.get(county)
        if county_data is None:
            state_data[county] = county_data = []
        county_data.append(item['city'])
    return data
您可以很容易地看到使用以下工具创建对象的位置:

import dis
dis.disassemble(make_dropdown_data.__code__)

这里有一个版本,它可以进行最少的
dict
查找(通过使用
dict.get
并检查
None
)和最少的空
dict
列表的创建(不使用类似于
dict.setdefault(…,[])
,其中可能的默认值总是被创建的)。对于数据的大小来说,这可能没有什么区别,但其他人比我先给出了我的原始答案,所以我认为这可能很好

def make_dropdown_data(items):
    data = {}
    for item in items:
        state = item['state']
        state_data = data.get(state)
        if state_data is None:
            data[state] = state_data = {}
        county = item['county']
        county_data = state_data.get(county)
        if county_data is None:
            state_data[county] = county_data = []
        county_data.append(item['city'])
    return data
您可以很容易地看到使用以下工具创建对象的位置:

import dis
dis.disassemble(make_dropdown_data.__code__)

您是否尝试过在
d
中循环,检查当前词典的状态是否存在于
输出中
,必要时创建词典,检查县是否存在,必要时创建词典,等等。?如果不是这样,你还试过什么?正如我在问题中所说的,我试过熊猫。顺便说一句,输出不是预先给出的,所以我无法与之进行任何比较。您是否尝试过在
d
中循环,检查当前词典的状态是否存在于
output
,必要时创建它,检查县是否存在,必要时创建,等等。?如果不是这样,你还试过什么?正如我在问题中所说的,我试过熊猫。顺便说一句,输出不是预先给出的,所以我无法与它进行任何比较。defaultdict的出色使用。但是我认为作为dd的
不是一个好主意。defaultdict的出色使用。但是我认为作为dd的
不是一个好主意。