It seems like my code doesn't work for lists with odd lengths and this is the error: "Oops, try again. median([6, 8, 12, 2, 23]) returned 12.5 instead of 8"

It has something to do with while loop but I can't see where's the problem.

def median(x):
n=[]
while len(x)!=0:
n.append(min(x))
x.remove(min(x))
if len(x)%2!=0:
r=len(x)/2
return n[r]
else:
p=len(x)/2-1
y=len(x)/2
z=n[p]+n[y]
return z/2.0

When I first discovered this I thought, cool! After a good long while something I'd read began to sink in that made it not so cool, anymore. Fudging code is what it is, when you consider that 2 is a counting number, 2.0 is not. 2 is 1/2 of 4. 2.0 is not; it's 1/2 of 4.0.

When a counting number is in the denominator, and we expect our quotient to be a float, then set the numerator to float. Avoid fudging the denominator. It's a mistake to think this is good coding. It is not. Implicit typing of values is a slippery slope that can be avoided by making everything perfectly clear. Be explicit.

return float(n[p] + n[y]) / 2

as an example.

Okay, now on to the real question, and the real answers. If we do not wish to mutate the list given to the function we can clone it with a shallow slice:

y = x[:]

Anything we do to y won't affect x which is in global scope and may have a particular order that is meant to be preserved. x is now out of the picture.

Next we sort, and let's cache the length, and the floor value of half this,

y.sort()
u = len(y)
n = u / 2

I didn't have to specify floor() since u is an integer and integer quotients are always floor values. Float quotients are floats, even when we use floor division...

a = 3.5
b = a // 2
print b # 1.0

Given the three data objects we have above, y, u, and n we have enough to work with.

if u % 2 != 0:
return y[n]
else:
return float(y[n-1] + y[n]) / 2

We've essentially done everything you did, with one exception, which I've written twice in this post. That one change and your code should work, too. No need to replace it.

Now the real problem surfaces. Remember the while loop used for sorting? Well it reduced x to nothing. That means len(x) is always 0 after the while loop.

p => -1
y => 0
z = float( 23 + 2 ) / 2 => 12.5

Change that to len(n) and things should start to work.

def median(x):
n=[]
while len(x) > 0:
n.append(min(x))
x.remove(min(x))
if len(n) % 2 != 0:
r = len(n) / 2
return n[r]
else:
p = len(n) / 2 - 1
y = len(n) / 2
z = float(n[p] + n[y])
return z / 2