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

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

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

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1704閲覧

[Python]予期せぬ中身変更

TakumiYamada

総合スコア11

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2016/06/23 04:32

###前提・実現したいこと
HITSアルゴリズムの計算プログラムを、以下のPythonソースコードのように実装したのですが、これを実行すると、HITSの引数として渡したHUBS,AUTHSの中身まで書き換えられてしまうのですが、どうしてでしょうか?HITSの最初で引数HUBS,AUTHSとローカル変数hubs,authsを区別できるようにしたはずなのですが・・・どなたか、解説をお願い致しますm(_ _)m

###該当のソースコード

Python

1import math 2from math import sqrt 3 4def init(): 5 hubs=[('a',1),('b',1),('c',1)] 6 auts=[('d',1),('e',1),('f',1)] 7 return hubs,auts 8 9hubs,auths=init() 10links=[('a','d'),('a','e'),('a','f'),('b','d'),('b','e'),('c','d')] 11 12def HITS(HUBS,AUTHS,links): 13 hubs=HUBS 14 auths=AUTHS 15 asum=0 16 hsum=0 17 for i in range(len(auths)): 18 asum=sum(h[1] for h in hubs if (h[0],auths[i][0]) in links) 19 auths[i]=(auths[i][0],asum) 20 for i in range(len(hubs)): 21 hsum=sum(a[1] for a in auths if (hubs[i][0],a[0]) in links) 22 hubs[i]=(hubs[i][0],hsum) 23 return hubs,auths

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

>>> hubs,auths=init() >>> hubs [('a', 1), ('b', 1), ('c', 1)] >>> auths [('d', 1), ('e', 1), ('f', 1)] >>> next_hubs,next_auths=HITS2(hubs,auths,links) >>> next_hubs [('a', 6), ('b', 5), ('c', 3)] >>> next_auths [('d', 3), ('e', 2), ('f', 1)] >>> hubs **[('a', 6), ('b', 5), ('c', 3)]**//ここは変わってほしくない >>> auths **[('d', 3), ('e', 2), ('f', 1)]**//ここも変わってほしくない

###試したこと
hubs,authsの要素をタプルにしたり長さ2の配列にしたり、色々試しましたが、やはりHITSの引数として渡したHUBS,AUTHSの中身まで変わってしまいます・・・

###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報

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

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

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

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

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

guest

回答1

0

ベストアンサー

Python は不勉強なのですが、スコープの問題(関数内で変数hubsを書き換えている)ではないでしょうか。関数内で使う変数の名前を変えてしまうか、下記のように引数を直接使うかどちらかで出来るのではないでしょうか。

Python

1def HITS(HUBS,AUTHS,links): 2 asum=0 3 hsum=0 4 for i in range(len(AUTHS)): 5 asum=sum(h[1] for h in HUBS if (h[0],AUTHS[i][0]) in links) 6 AUTHS[i]=(AUTHS[i][0],asum) 7 for i in range(len(HUBS)): 8 hsum=sum(a[1] for a in AUTHS if (HUBS[i][0],a[0]) in links) 9 HUBS[i]=(HUBS[i][0],hsum) 10 return HUBS,AUTHS

追記:

Pythonの引数は参照渡しなんですね。関数内部に新たに配列を作って、それを返すのはいかがでしょう。

Python

1def HITS(HUBS,AUTHS,links): 2 ares=[] 3 hres=[] 4 asum=0 5 hsum=0 6 for i in range(len(AUTHS)): 7 asum=sum(h[1] for h in HUBS if (h[0],AUTHS[i][0]) in links) 8 ares[i]=(AUTHS[i][0],asum) 9 for i in range(len(HUBS)): 10 hsum=sum(a[1] for a in AUTHS if (HUBS[i][0],a[0]) in links) 11 hres[i]=(HUBS[i][0],hsum) 12 return hres,ares

【Pythonの引数はすべて参照渡し - Qiita】
http://qiita.com/urakarin/items/1d6e0e76bffb9297606e

【Pythonの引数は全て参照渡しの件について - k_kinukawa's diary】
http://kkinukawa.hatenablog.com/entry/20100518/1274189687

【[Python]常識ですよ?と言われないための引数入門 - くろのて】
http://note.crohaco.net/2014/python-argument-intro/

投稿2016/06/23 04:37

編集2016/06/23 04:56
kei344

総合スコア69407

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

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

TakumiYamada

2016/06/23 04:47

ありがとうございます。残念ながら、元のhubs,authsの中身は書き換えられてしまいます・・・
kei344

2016/06/23 04:56

追記しました。
TakumiYamada

2016/06/23 05:02

解決しました!丁寧な解説ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問