动态更改 Streamlit.multiselectbox 选项

Dynamically alter Streamlit.multiselectbox options

我的 streamlit 应用程序的边栏中有一个 multiselect 框。不失一般性:

因此,如果 1 被 selected,我想从可能的 select 离子列表中删除 2,但 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[:]

有什么想法可以实现吗?

方法一

这是一种方法,在小部件上提供帮助,只允许用户 select 1 和 2,但如果两者都被 selected,我们必须过滤掉 2。然后你可以只使用经过验证的 selection.

代码
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))
输出

将鼠标悬停在 ? 上以显示帮助。

方法二

选项 1 或 2 使用单选按钮,其余选项用于多个select。

代码
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))
输出

方法三

select编辑 1 时删除 2,然后重新运行以更新选项。同样,当 selected 删除 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))
输出