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

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

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

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

Q&A

解決済

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

ngmg
ngmg

総合スコア67

Python 3.x

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

3回答

0グッド

0クリップ

206閲覧

投稿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)

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答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

総合スコア10557

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

0

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

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

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

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

投稿2022/11/28 05:41

teamikl

総合スコア8557

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

ngmg

2022/11/28 06:38

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

0

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

投稿2022/11/28 05:35

ozwk

総合スコア13084

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

ngmg

2022/11/28 06:38

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

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Python 3.x

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