Python 根据用户在另一个清单中输入的内容更新清单

Python Dash update checklist based on user input in another checklist

目标:在用户选择他们感兴趣的国家后,用所有选项更新城市清单(例如,用户从清单中选择法国和德国,城市清单将更新为波尔多、里昂、马赛和柏林)。

问题:当我在上次回调中输入国家和城市清单时,出现 TypeError: unhashable type: ‘list’。

我有一本地区字典和另一本国家字典:

# Create country options for regions
country_options = {
    'EMEA': ['France', 'Germany'],
    'APAC': ['Australia'],
    'Americas': ['United States'],
}

# Create city options for countries
city_options = {
    'France': ['Bordeaux', 'Lyon', 'Marseille'],
    'Germany': ['Berlin'],
    'Australia': ['Lawnton', 'Carrum Downs'],
    'United States': ['Chicago', 'New York', 'Orlando', 'Seattle'],
}

那么这是我构建单选项目和清单的布局:

dcc.RadioItems(id='region_radio',
               options=[{'label': str(c), 'value': c} for c in sorted(df['Region'].unique())],
               labelStyle={'display': 'block'},
               inputStyle={'margin-right': '5px'}),


html.Label('Country:', style={'margin-left': '10px', 'font-size': 18, 'color': 'white', 'font-weight': 'bold'}),
dcc.Checklist(id='country_checklist', className='checkbox',
              value=[],
              labelStyle={'display': 'block'},
              inputStyle={'margin-right': '5px'}),
                

html.Label('City:', style={'margin-left': '10px', 'font-size': 18, 'color': 'white', 'font-weight': 'bold'}),
dcc.Checklist(id='city_checklist', className='checkbox',
              value=[],
              labelStyle={'display': 'block'},
              inputStyle={'margin-right': '5px'}),

到目前为止我所做的是针对地区单选项目,当用户选择 3 个选项中的任何一个时,国家清单将填充该地区的国家:(有效)

# Update country checklist based on user input in region
@callback(
    Output('country_checklist', 'options'),
    Input('region_radio', 'value')
)
def set_country_options(selected_region):
    if not selected_region:
        return dash.no_update
    else:
        return [{'label': i, 'value': i} for i in country_options[selected_region]]

不过,我正在尝试做同样的事情,因为当用户选择一个国家/地区以拥有该国家/地区特有的城市时:

# Update city checklist based on user input in country
@callback(
    Output('city_checklist', 'options'),
    Input('country_checklist', 'value')
)
def set_country_options(selected_country):
    if not selected_country:
        return dash.no_update
    else:
        return [{'label': i, 'value': i} for i in city_options[selected_country]]

但是我收到一个错误:TypeError: unhashable type: ‘list’

当用户从清单中选择 country/ies 以填充城市时,您能告诉我如何让它工作吗?

问题在于,在第二种情况下,您处理的是值列表而不是单个值。

region_radiovalue 属性 将始终引用单个值。

city_checklistvalue 属性指的是值列表。

您需要以不同的方式处理这些情况。

重现错误的示例

city_options = {
    'France': ['Bordeaux', 'Lyon', 'Marseille'],
    'Germany': ['Berlin'],
    'Australia': ['Lawnton', 'Carrum Downs'],
    'United States': ['Chicago', 'New York', 'Orlando', 'Seattle'],
}
selected_country = ['Berlin'] # value could refer to multiple values so 'Berlin' is wrapped in a list
city_options[selected_country]

所以你需要另一个循环来遍历每个 selected_country.

options = []
for selected_country in selected_countries:
  for city_option in city_options[selected_country]:
    options.append({'label': city_option, 'value': city_option})

return options

列表理解版

return [{'label': city_option, 'value': city_option} for selected_country in selected_countries for city_option in city_options[selected_country]]