はじめに
備忘録です。
何か他にもいい方法があったら教えて下さい。
本題
Streamlitを使用すると、簡単に描画アプリを作成することができます。
また、Rerunボタンを押すことで、すぐにソースコードの変更を反映できます
ここで問題が発生しました。
例えば以下のようにinputをリストで保持したい場合
import streamlit as st
lst = []
input = st.text_input('何か入力して下さい')
lst.append(input)
st.table(lst)
appの出力はこのようになります。
ここで何かを入力してみます。
aaaが反映されたことがわかります。
次に新しくbbbを追加してみます。
bbbは追加されましたが、すでにあったaaaは反映されていませんでした。
なのでコードを修正してみました。チェックボックスがチェックされていると入力が止まるような
感じにしてみました。
lst = []
i = 0
while True:
input = st.text_input('何か入力して下さい', key=str(i))
lst.append(input)
i += 1
if st.checkbox('stop'):
break
st.table(lst)
streamlitで入力をループにするにはよくないっぽいです。(できたとしても入力欄が無限に出力されそう)
#原因
原因としてはStreamlitでRerunを実行すると、全てのデータをロードしてしまうからでした。
Rerunはボタンを押さなくても、入力欄での追加・変更がされるだけでも自動的に行われます。
そこでStreamlitのcache機能を使用します。
Cacheとは
cacheはStreamlitのデコレーターです。
関数の前に@st.cacheをつけることで使用することができます。
簡単に言うとcacheを利用できるので、一度使った関数は引数が変わらないと変更が行われない感じです。
(変更される条件は他にも複数存在します。詳しくはドキュメントを参考にしてみて下さい。)
改善
それではcacheを使用してコードを変更してみます。
@st.cache(allow_output_mutation=True)
def cache_lst():
lst = []
return lst
lst = cache_lst()
input = st.text_input('何か入力して下さい')
if st.checkbox('clear'):
caching.clear_cache()
lst = cache_lst()
elif input:
lst.append(input)
st.table(lst)
すると、以下のようにリストに値が保持できていることがわかります。
また、clearのチェックボックスをチェックするとリストを初期化することができます。
これを使うことで、要素の削除や変更を行うことができます。
また、このときリストはimmutableなので、要素の変更を行う際に代入をする形をとると変更が反映されません。
@st.cache(allow_output_mutation=True)
def cache_lst():
lst = []
return lst
lst = cache_lst()
input = st.text_input('何か入力して下さい')
if st.checkbox('clear'):
caching.clear_cache()
lst = cache_lst()
elif input:
lst.append(input)
if st.checkbox('delete'):
delete = st.selectbox('削除する要素を選択して下さい', options=lst)
if st.button('Delete'):
lst.remove(delete)
st.success(f'Delete : {delete}')
if st.checkbox('change'):
change_from = st.selectbox('変更する要素を選択して下さい', options=lst)
change_index = lst.index(change_from)
change_to = st.text_input('何に変更しますか')
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)
削除した時
変更した時
※削除・変更・追加をする際はinput欄に文字が入っていると勝手に追加されることがあるので注意して下さい