Yash Kumar Verma
Yash Kumar Verma

Reputation: 9620

Value of variable changing when assigned value through max function

This was a relatively simple problem, to list the elements with maximum value from a nested list.

So I made this function, which

  1. finds the element with maximum attribute
  2. replaces the maximum attribute by 0
  3. Finds the element(s) with max attribute
  4. return the elements.

While doing so, I got stuck on step 2 and been there ever since.

Here's the function :

def secondMax(data):
    x = max(data, key=lambda x:x[1])

    for i in range(0, len(data)):
        if(data[i][1] == x[1]):
            data[i][1] = 0
            print(x) #             prints ['yash',0]
    print(x) #                     prints ['yash',0]
    return data

and when i run the code, this is the output

running

# data being fed
data = [['yash', 5.0], ['akash', 5.0], ['harsh', 3.0], ['dj', 4.0], ['ashutosh', 4.0]]
secondMax(data)

OUTPUT

# output 
['yash', 0]
['yash', 0]
[['yash', 0], ['akash', 5.0], ['harsh', 3.0], ['dj', 4.0], ['ashutosh', 4.0]]

Now, why is not the second element, (akash, 5.0) being set to (akash, 0)? As far as I can understand, the value of x should not change (which is changing) and causing this.

Why is this happening?

Upvotes: 0

Views: 548

Answers (2)

shaik moeed
shaik moeed

Reputation: 5785

The max_user in the below code, is referencing the same object i.e., nested list in data. When we changed the inner value of the nested list, it is getting reflected in our max_user as well(as it referenced to the same object, not to inside values).

So, I have taken a .copy() of max_user and used it for comparisons.

Made small corrections and you can iterate over list and access it in loop no need of using range,

>>> def secondMax(data):
    max_user = max(data, key=lambda x:x[1])
    _temp = max_user.copy()

    for user in data:

        if user[1] == _temp[1]:
            user[1] = 0
            print(_temp)
    print(_temp)
    return data

Output:

>>> secondMax(data)
['yash', 5.0]
['yash', 5.0]
['yash', 5.0]
[['yash', 0], ['akash', 0], ['harsh', 3.0], ['dj', 4.0], ['ashutosh', 4.0]]

Upvotes: 0

ndrplz
ndrplz

Reputation: 1644

Looks like

x = max(data, key=lambda x:x[1])

is returning a reference to the maximum element. So when you set its value to zero during the first iteration doing

        if(data[i][1] == x[1]):
            data[i][1] = 0

you are actually changing the value you use for comparison. From now on x[1] will be zero. So basically 'akash' does not match because you are comparing its value 5.0 with a 0.0, which clearly returns False.

Upvotes: 1

Related Questions