Динамически изменять параметры Streamlit.multiselectbox

#python #multi-select #streamlit

#python #множественный выбор #streamlit

Вопрос:

У меня есть multiselectbox на боковой панели моего приложения streamlit. Без потери общности:

  • У меня есть 10 вариантов для размещения в этом multiselectbox (это числа 1 … 10)
  • Пользователь не может выбрать оба 1 и 2 одновременно

Поэтому я хотел бы удалить 2 из списка возможных вариантов выбора, если 1 выбрано, но streamlit, похоже, не имеет для этого возможности, поэтому я попытался обернуть его в цикл, который также завершается неудачей ( DuplicateWidgetID: There are multiple identical st.multiselect widgets with the same generated key. ):

 options = [1,2,3,4,5,6,7,8,9,10]

space = st.sidebar.empty()
answer, _answer = [], None
while True:
    if answer != _answer:
        answer.append(space.multiselectbox("Pick a number",
                                           options,
                                           default=answer
                                           )
                      )
        options = [o for o in options if o not in answer]
        if 1 in options:
            if 2 in options: options.remove(2)
        if 2 in options:
            if 1 in options: options.remove(1)
        _answer = answer[:]
  

Есть мысли о том, как я мог бы этого добиться?

Комментарии:

1. Похоже , это означает, что это невозможно сделать только с StreamLit

2. О The user may not select both 1 and 2 simultaneously том, как вы сообщаете об этом пользователю?

3. «как вы сообщаете об этом пользователю?» Отключив опцию 2 , когда пользователь выбирает опцию 1 , так что 2 она больше не выбирается. Это позволило бы использовать более сложную логику мьютексов

4. Я предоставил метод 2 в своем пересмотренном ответе, разве этого недостаточно?

5. Ответ обновлен, добавлен метод 3, чтобы удалить 2 или 1, если выбрано 1 или 2.

Ответ №1:

Способ 1

Вот один из подходов, предоставляющий справку по виджету и просто позволяющий пользователю выбирать как 1, так и 2, но затем мы должны отфильтровать 2, если выбраны оба. Затем вы можете просто использовать проверенный выбор.

Код
 import streamlit as st

ms = st.sidebar.multiselect('Pick a number',  list(range(1, 11)),
    help='Choose either 1 or 2 but not both. If both are selected 1 will be used.')

if 1 in ms and 2 in ms:
    ms.remove(2)

st.write('##### Valid Selection')
st.write(str(ms))
  
Вывод

Наведите курсор мыши на ? , чтобы показать справку.

введите описание изображения здесь

Способ 2

Используйте переключатель для параметров 1 или 2, а остальные для multiselect.

Код
 import streamlit as st

rb = st.sidebar.radio('Pick a number', [1, 2])

ms = st.sidebar.multiselect('Pick a number',  list(range(3, 11)))

selected = ms
selected.append(rb)

st.write('##### Valid Selection')
st.write(str(selected))
  
Вывод

введите описание изображения здесь

Способ 3

При выборе 1 удалите 2, а затем повторите, чтобы обновить параметры. Аналогично, когда выбрано значение 2, удалите значение 1 и повторите запуск, чтобы обновить параметры.

Код
 import streamlit as st


init_options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


if 'options' not in st.session_state:
    st.session_state.options = init_options
if 'default' not in st.session_state:
    st.session_state.default = []


ms = st.sidebar.multiselect(
    label='Pick a number',
    options=st.session_state.options,
    default=st.session_state.default
)

# If 1 is selected, remove the 2 and rerun.
if 1 in ms:
    if 2 in st.session_state.options:
        st.session_state.options.remove(2)
        st.session_state.default = ms
        st.experimental_rerun()

# Else if 2 is selected, remove the 1 and rerun.
elif 2 in ms:
    if 1 in st.session_state.options:
        st.session_state.options.remove(1)
        st.session_state.default = ms
        st.experimental_rerun()


st.write('##### Valid Selection')
st.write(str(ms))
  
Вывод

введите описание изображения здесь

Комментарии:

1. Хотя это действительно простой способ решения проблемы UX (т. Е. Информирования пользователя о проблеме), он технически не ограничивает пользователя от неправильного выбора. Поэтому это не ответ на вопрос, хотя он полезен другими способами

2. Добавлен 2-й метод в ответе для решения проблемы.

3. Добавлен метод 3, чтобы удалить 2 или 1, если выбрано 1 или 2.