The value of st.session_state cannot be found in the loop

My code:

  import streamlit as st
  from streamlit import session_state as ss

  if 'selected_item' not in ss:
    ss.selected_item = None
  if 'start_btn' not in ss:
    ss.start_btn = False

  # The dictionary is actually going to be dynamic
  lists = {
    "2021": ['21消费总账', '21娱乐', '21生活', '21美食'],
    "2022": ['22消费总账', '22娱乐', '22生活', '22美食'],
    "2023": ['23消费总账', '23娱乐', '23生活', '23美食'],
  }
  data_tabs = list(lists.keys())
  tabs = st.tabs(data_tabs)
  for i in range(len(data_tabs)):
    with tabs[i]:
      curr = st.radio("请在下面列表中选择您要展示类型", lists[data_tabs[i]], index=None)
      ss.selected_item = curr
      if st.button('OK', key=data_tabs[i]):
        ss.start_btn = True
  if ss.start_btn:
    st.write('您的选择:', ss.selected_item)

In the code above, I ran into some problems and wanted to ask for some solutions:

  1. The value is assigned in the loop, but it cannot be obtained outside the loop


    But in the last tab, you can get, I guess, the loop problem, but I can’t think of a solution

  2. When you switch to a new tab, the contents below should be cleared

  3. When I switch tab, how do I reset the radio selection

Hi,

Have you thought about using a st.selecbox approach, making the code simpler and more pragmatic?

import streamlit as st
from streamlit import session_state as ss


lists = {
    "2021": ['21消费总账', '21娱乐', '21生活', '21美食'],
    "2022": ['22消费总账', '22娱乐', '22生活', '22美食'],
    "2023": ['23消费总账', '23娱乐', '23生活', '23美食'],
}

if 'selected_items' not in ss:
    ss.selected_items = {tab: None for tab in lists.keys()}
if 'selected_tab' not in ss:
    ss.selected_tab = None

data_tabs = list(lists.keys())
selected_tab = st.selectbox("选择年份", data_tabs, index=data_tabs.index(ss.selected_tab))


curr = st.selectbox("请在下面列表中选择您要展示类型", lists[selected_tab], index=lists[selected_tab].index(ss.selected_items[selected_tab]))

if st.button("OK"):
    ss.selected_items[selected_tab] = curr
    ss.selected_tab = selected_tab


if ss.selected_tab and ss.selected_items[ss.selected_tab] is not None:
    st.write('您的选择:', ss.selected_items[ss.selected_tab])
else:
    st.write("请选择一个项目")

Thank you for your suggestion and I have tried it. It is indeed OK. However, I wonder if there is a solution to the problem of using radio and tabs above. Or do you know the reason for the appeal problem? Look forward to your sharing

ss.selected_item is assigned once per iteration of the loop. After the loop it has the value assigned in the last iteration, which initially is indeed None.

I don’t think you can do that. There is no builtin way for the application to detect when you switch to a tab.

I think I understand. Thank you for your explanation

Hello @Oscar1,

Can you please try this:

import streamlit as st

if 'selected_item' not in st.session_state:
    st.session_state.selected_item = {}
if 'current_tab' not in st.session_state:
    st.session_state.current_tab = None
if 'start_btn_pressed' not in st.session_state:
    st.session_state.start_btn_pressed = False

lists = {
    "2021": ['21消费总账', '21娱乐', '21生活', '21美食'],
    "2022": ['22消费总账', '22娱乐', '22生活', '22美食'],
    "2023": ['23消费总账', '23娱乐', '23生活', '23美食'],
}

data_tabs = list(lists.keys())
tabs = st.tabs(data_tabs)

for i, tab_name in enumerate(data_tabs):
    if tabs[i]:
        # Detect tab switch and reset state
        if st.session_state.current_tab != tab_name:
            st.session_state.selected_item[tab_name] = None
            st.session_state.start_btn_pressed = False
            st.session_state.current_tab = tab_name
        
        with tabs[i]:
            # Use dynamic keys for each tab's radio to maintain their state separately
            curr = st.radio("请在下面列表中选择您要展示类型", lists[tab_name], index=0, key=f'radio_{tab_name}')
            st.session_state.selected_item[tab_name] = curr
            
            if st.button('OK', key=f'btn_{tab_name}'):
                st.session_state.start_btn_pressed = True
                st.write('您的选择:', st.session_state.selected_item[tab_name])

Yes, this is what I was looking to perform @nly, good work on your part.
Thank you.

@nly Happy to help! Let me know if you might have any further questions

Kind Regards,
Sahir

P.S. Lets connect on LinkedIn!

Hello, thank you for your solution :smiling_face:

1 Like