3

I am trying to solve a problem. While trying to change list values, I have observed a strange list behaviour. I can't change the values of the list elements.

top = list(map(int, raw_input().split()))
staff = list(map(int, raw_input().split()))

ceo  = top[0]
coo = top[1]
cto = top[2]

top.extend(staff)
alls = sorted(top)
tot = len(alls)
print(alls)

alls[tot/2], alls[alls.index(ceo)] = alls[alls.index(ceo)], alls[tot/2]
print(alls)

alls[0], alls[alls.index(coo)] = alls[alls.index(coo)], alls[0]
alls[-1], alls[alls.index(cto)] = alls[alls.index(cto)], alls[-1]

print(alls)

Here is the output of the program:

Input:

13 11 17
12 10

Output

[10, 11, 12, 13, 17]
[10, 11, 12, 13, 17]
[10, 11, 12, 13, 17]

Why are all list values not changing? Am I doing something wrong?

EDIT: Question statement: https://www.hackerearth.com/codejunk/algorithm/steal-the-show/

I know my approach is not the best way to solve this problem but I just want to know why values of list is not changing?

11
  • 1
    what is the code supposed to be doing exactly Commented Jul 3, 2015 at 18:03
  • Its a question of an ongoing contest so can't link the question. Anyways does it matter? Commented Jul 3, 2015 at 18:04
  • 2
    Yes it matters because you have just dumped a load of code with zero explanation of what should actually happen and why Commented Jul 3, 2015 at 18:06
  • 1
    Don't you just want to sort the staff, put the ceo in the middle with the other two either end? Commented Jul 3, 2015 at 18:12
  • 1
    The logic is simple, sort the staff then put the smaller of the coo and cto at the start and the other at the end. The only other logic is when there will be an even number of people, then you have two choices for the ceo, you just have to find whether to the the right or left will mean the diff will be less. Commented Jul 3, 2015 at 20:19

1 Answer 1

5

The problem here is your combination of operators. I take the first assignment as example and dissect it:

alls[tot/2], alls[alls.index(ceo)] = alls[alls.index(ceo)], alls[tot/2]

What will happen:

  1. ceo is 13 in the beginning, so alls.index(ceo) will be 3 when the statement is executed ... but wait ... this holds for the time before the assignment.

  2. First the values before the assignment will be evaluated. alls[alls.index(ceo)] will be 13 -- no wonder, because ceo is 13.

  3. alls[tot/2] will be 12, because tot/2 is 2 (indexes will be integers, so the part behind the comma will be lost).

  4. So on the right side we will get (13, 12).

  5. Now, to the assignment. alls[tot/2] will be assigned first (but you can not trust on it, since this is implementation detail!).

  6. So alls[2] will be 13 !!

  7. Now, the second part of the assignment .... alls.index(ceo) will be 2 .... WHAT??

The reason is, that alls currently holds [10, 11, 13, 13, 17] ... and alls.index(ceo) will be evaluated and finds 13 at the position 2 before it finds the other 13 at position 3.

So what will happen -- alls[2] will be assigned 12 -- the list is back again to the previous content.

The reason is, that you use combined operators and always evaluate sub-expressions new without taking into account, that sub-expressions will change in the process of evaluation.

You can prevent this, by assigning results of some sub-expressions to variables and using them instead making the expressions complicated. Specifically, sub-expressions that might change inside the main expression should be evaluated before the expression and stored in a variable.

Sign up to request clarification or add additional context in comments.

5 Comments

Specifically, calculate the indices tot/2 and alls.index(ceo) and store them in variables before you make the swap. (The second one is the problematic one.)
You are right. I hoped, that it would be clear, that alls.index(ceo) is the culprit here. I wanted to formulate in a way, that it applies to other similar situations. tot/2 is not a problem here, since tot does not change in the process.
Yeah, that was more a message for the OP. I knew you got it. ;)
Oh my bad. Was trying to solve problem quickly. Thank you! Juergen and Bill.
@BilltheLizard: No offence taken. I added some sentence that should make the situation more clear.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.