Rushil Paul
Rushil Paul

Reputation: 2048

What's wrong with this simple python code?

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.

After taking n as input, n space separated integers are inputted on the next line.

The problem is very weird - for the following input:

7
6 17 5 3 13 8 10

when I uncomment #print m in the code, it prints 3 3 0 3 0 (expected output is 3 5 6 8 10); also, an IndexError occurs (that is just a symptom of the real problem).

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)

I did a lot of debugging by printing values of variables at different locations, but couldn't reason out anything.

Upvotes: 1

Views: 126

Answers (3)

Rik Poggi
Rik Poggi

Reputation: 29312

I'm not really following your code, but this:

ar = index = [0]*n

seems quite strange to do in python, try to replace it with:

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

And see if it works.

This example, may help to see why that seems strange:

>>> 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]

You may be interested in taking a loook at Other languages have "variables", Python has "names".

Side note:

Try to make your code more readable:

  • 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.

Also (if I understood what you're trying to do), your code could be rewritten like:

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]]

Upvotes: 4

Benedict
Benedict

Reputation: 2821

You'd have a lot less trouble if you learn and use the higher level powerful features python provides. Less code is easier to understand and debug:

>>> 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]

Upvotes: 2

Reinstate Monica
Reinstate Monica

Reputation: 4723

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

Somewhat more pythonic would be

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])]

which gives [3, 5, 6, 8, 10] for your input (no need to give n explicitly).

Upvotes: 2

Related Questions