このシンプルなPythonコードで何が問題になっていますか?

n = int(raw_input())
s = raw_input().strip().split(' ')
ar = index = [0]*n; done = [False]*n
for a in range(n): ar[a] = int(s[a])
k=0
for a in range(5):
     m = 1000000001
     for i in range(n):
         if done[i]: continue
         if ar[i] < m: m = ar[i]
     if m == 1000000001: 
         sys.stdout.write('-1\n')
         break
     #print m
     for i in range(n):
         if ar[i] == m:
             index[k] = i
             k+=1
             done[i]=True

print index

The algorithm is quite simple. ar is an array of n (>= 5) integers. I intend to store the 0 based positions of the first 5 smallest integers of the array in index.

n を入力した後、 n スペースで区切られた整数が次の行に入力されます。

問題は非常に奇妙です - 次の入力について:

7
6 17 5 3 13 8 10

コード内の #print m のコメントを外すと、 3 3 0 3 (期待される出力は 3 5 6 8 10 )です。また、 IndexError が発生します(実際の問​​題の単なる症状です)。

Variable done is working as expected (it contains a list of boolean values, where, if done[i] is True, then ar[i] should not be taken into consideration while looking for min(ar)

私はさまざまな場所で変数の値を表示することで多くのデバッグを行いましたが、何かを理由づけできませんでした。

1

3 答え

私は実際にあなたのコードに従っているわけではないが、これは:

ar = index = [0]*n

Pythonでやるのが奇妙に思えますが、それを次のように置き換えてみてください:

ar = [0]*n
index = [0]*n

それが動作するかどうかを確認してください。

この例は、なぜそれが奇妙に見えるかを見るのに役立ちます:

>>> a = b = [0] * 5
>>> a
[0, 0, 0, 0, 0]
>>> b
[0, 0, 0, 0, 0]
>>> a[1] = 2
>>> a
[0, 2, 0, 0, 0]
>>> b
[0, 2, 0, 0, 0]

あなたは他の言語には「変数」があり、Pythonには「名前」があります

サイドノート:

コードを読みやすくするようにしてください:

  • go to a new line when required, there's no actual need for ;
  • don't write for-loops/if-statements in one line: there's list comprehension for that.

また、(私があなたがしようとしていることを理解していれば)、あなたのコードは次のように書き直すことができます:

s = raw_input().strip().split(' ')
ar = [(int(num),i) for i,num in enumerate(s)]
ar.sort()
print [a[1] for a in ar[:5]]
4
追加された
ありがとう!それはうまくいった!私はa = b = []を書くことでそれを知らなかったが、pythonはa、b
追加された 著者 Rushil,
@リカルド:それをクリアしていただきありがとうございます。
追加された 著者 Rik Poggi,
@Rushil:Pythonオブジェクトは常に値渡しではなく参照渡しされます。 "a = b = []"は "b = []; a = b"と同じですので、両方の変数が同じオブジェクトを指していることになります。
追加された 著者 Ricardo Cárdenes,

ar = index = [0]*n should be ar = [0] * n; index = [5] * 5. The way you wrote it, ar and index are the same list.

幾分もっとピ

from heapq import nsmallest
s = map(int, raw_input().split())
print [ind for value, ind in nsmallest(5, enumerate(s), key=lambda x: x[1])]

あなたの入力に対して [3、5、6、8、10] を与えます(明示的にnを与える必要はありません)。

2
追加された
コードを短縮してくれてありがとう。ところで、index = [5] * 5は動作しません。インデックスのサイズは少なくともnにする必要があります(ar []の整数が繰り返される場合)
追加された 著者 Rushil,
@Rushil:ああ、それは説明しています:-)あなたは繰り返しがあり、5つの最小の整数のすべての位置を保存します。その場合、私の答えはあなたのものとは異なる結果をもたらします。
追加された 著者 WolframH,

Pythonが提供するより高レベルの強力な機能を習得して使用すれば、問題は少なくなります。少ないコードで理解しやすくデバッグすることができます。

>>> s=[6,17,5,3,13,8,10]
>>> d=dict(enumerate(s))
>>> sd=sorted(d, cmp=lambda x,y: cmp(d[x], d[y]))
>>> [d[sd[v]] for v in range(5)]
[3, 5, 6, 8, 10]
2
追加された
それに感謝します。私はちょうどそれがどのように動作するかを見るために、PythonにCコードスニペットを変換しました:-)
追加された 著者 Rushil,