[PYTHON] Streamlit prevents list initialization

Introduction

It is a memorandum. Please let me know if there is any other good way.

Main subject

Streamlit makes it easy to create drawing apps. You can also immediately reflect the source code changes by pressing the Rerun button. スクリーンショット 2021-01-18 13.39.52.png

There was a problem here. For example, if you want to keep the input in a list like below

import streamlit as st

lst = []
input = st.text_input('Please enter something')
lst.append(input)
st.table(lst)

The output of the app looks like this. スクリーンショット 2021-01-18 13.50.09.png Let's enter something here. スクリーンショット 2021-01-18 13.52.37.png You can see that aaa is reflected. Next, try adding a new bbb. スクリーンショット 2021-01-18 13.53.34.png bbb was added, but the existing aaa was not reflected.

So I modified the code. Input stops when the check box is checked I tried to feel it.

lst = []
i = 0
while True:
    input = st.text_input('Please enter something', key=str(i))
    lst.append(input)
    i += 1
    if st.checkbox('stop'):
        break
st.table(lst)

The output looks like this: スクリーンショット 2021-01-18 13.59.25.png

It seems that it is not good to loop the input with streamlit. (Even if it can be done, the input field seems to be output infinitely)

Cause

The cause was that when Rerun was executed with Streamlit, all the data was loaded. Rerun is automatically performed even if you add or change in the input field without pressing the button. Therefore, use Streamlit's cache function.

What is Cache?

cache is a Streamlit decorator. It can be used by prefixing the function with @ st.cache. Simply put, you can use cache, so once you use a function, it doesn't change unless the argument changes. (There are several other conditions that can be changed. For details, refer to Documentation.)

Improvement

Now let's change the code using cache.

@st.cache(allow_output_mutation=True)
def cache_lst():
    lst = []
    return lst

lst = cache_lst()
input = st.text_input('Please enter something')
if st.checkbox('clear'):
    caching.clear_cache()
    lst = cache_lst()
elif input:
    lst.append(input)
st.table(lst)

Then, you can see that the values ​​can be retained in the list as shown below. スクリーンショット 2021-01-18 14.58.41.png

You can also initialize the list by checking the clear checkbox. You can use it to delete or change elements. Also, since the list is immutable at this time, the change will not be reflected if you take the form of assigning when changing the element.

@st.cache(allow_output_mutation=True)
def cache_lst():
    lst = []
    return lst

lst = cache_lst()
input = st.text_input('Please enter something')
if st.checkbox('clear'):
    caching.clear_cache()
    lst = cache_lst()
elif input:
    lst.append(input)

if st.checkbox('delete'):
    delete = st.selectbox('Select the element to delete', options=lst)
    if st.button('Delete'):
        lst.remove(delete)
        st.success(f'Delete : {delete}')

if st.checkbox('change'):
    change_from = st.selectbox('Select the element you want to change', options=lst)
    change_index = lst.index(change_from)
    change_to = st.text_input('What do you want to change')
    if st.button('Change'):
        lst.remove(change_from)
        lst.insert(change_index, change_to)
        st.success(f'Change {change_from} to {change_to}')
st.table(lst)

スクリーンショット 2021-01-18 15.17.53.png When deleted スクリーンショット 2021-01-18 15.18.36.png When changed スクリーンショット 2021-01-18 15.19.55.png ** * Please note that when deleting / changing / adding, if there are characters in the input field, they may be added without permission **

reference

Improve app performance Introduction to Streamlit

Recommended Posts

Streamlit prevents list initialization
Multidimensional array initialization of list