質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

3回答

532閲覧

python 2つリストの差分、複製、更新について

ngmg

総合スコア72

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2022/11/28 05:21

編集2022/11/28 05:23

実現したいこと

ベースとカレントの2つのリストを比較し差分があればprintし、ベースリストを更新(カレントリストと同じにする)したいのですがエラーがでてしまいます。

再起動等でベースリストが空の場合はファイルから取り込んでおり、その後はループしています。

base_stock = copy.copy(current_stock)
この1行をなくせばエラーはなくなるので悪さしているのはここと推測していますが全く理由がわからない状態です。

発生している問題・エラーメッセージ

base_stock.append(k) UnboundLocalError: local variable 'base_stock' referenced before assignment

該当のソースコード

base_stock = [] current_stock = [] async def main(current_stock): # もしリストが空の時(再起動等のとき) if any(base_stock) == False: # ベースデータの読み込み with open("is_stock.txt", mode='r', encoding='utf-8') as f: #base_stock = f.read().splitlines() for k in f.read().splitlines(): base_stock.append(k) # 差分を取得 print(base_stock) diff_list = set(base_stock) ^ set(current_stock) # もし差分があった場合 if any(diff_list) == True: # 差分リストをループ処理 for title in diff_list: # 差分アイテムがベースデータにあるかどうか if title in base_stock: print(title + "はベースにあってカレントにない") else: print(title + "はカレントにあってベースにない") # ベースデータを更新 #base_stock = current_stock.copy() base_stock = copy.copy(current_stock) else: print("変更なし") #base_stock = copy.copy(current_stock)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

pythonの変数のスコープはこんな感じです。

python

1a = 10 2b = 20 3c = 30 4def fun_x(): 5 global c 6 print(a) # 10 7 b = 200 8 print(b) # 200 9 c = 300 10 print(c) # 300 11print(a) # 10 12print(b) # 20 13print(c) # 300

関数の外で定義されている変数は、aのように代入しない(左辺値にしない)限り参照できますが、bの様に変更してしまうと、ローカルな変数になってしまい、外の変数とは別のものになります。
関数の内部で変数を変更したい場合、cのようにglobal宣言すれば可能です。

質問の件も、「base_stock = current_stock.copy()」を下の方に入れることで、base_stockが関数ローカルな変数になってしまい、この代入より前に参照しているので未定義でエラーになるのです。


おまけ

関数で変数をglobal変数として変更するのは便利な場面もありますが、変数の値がどこで変更されているのかがわかりにくくなる弊害があるので避けることが多いです。
興味があれば、「global変数 弊害」などで検索みるといいでしょう。

投稿2022/11/28 05:50

TakaiY

総合スコア12743

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

「変数への代入」がある場合、
変数 base_stock は、グローバル宣言がされてないので
ローカル変数として扱われています。

ローカル変数としてみた場合、変数定義は関数の後半で行われるので
前半での変数参照はエラーとなります。

解決策: 関数内でグローバル宣言
global base_stock

参考: Python プログラミング FAQ
なぜ変数に値があるのに UnboundLocalError が出るのですか?

投稿2022/11/28 05:41

teamikl

総合スコア8664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ngmg

2022/11/28 06:38

辞書やリストはグローバル宣言しなくても使えると思っていてドツボにはまっていました。 ありがとうございます。
guest

0

変数に代入を行おうとした場合、その変数はローカル変数として解釈されます。
メソッドの適当なところ(先頭あたり)でglobal指定をつけて宣言する必要があります。

投稿2022/11/28 05:35

ozwk

総合スコア13521

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ngmg

2022/11/28 06:38

辞書やリストはグローバル宣言しなくても使えると思っていてドツボにはまっていました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問