scores = [[0,0]]*10
scores[1][1] += 1
print(scores)
>>[[0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1]]
I want to increment at a specific position in a nested list in python, but am incrementing the entire list instead. Can anyone explain this behavior?
This is because python is first creating the list, then is creating the reference ten times. In other words, using this method only one list is created. Try this:
scores = []
for i in range(10):
scores.append([0, 0])
scores[1][1] += 1
print(scores)
Output:
[[0, 0], [0, 1], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]
scores = [[0,0]]*10 makes 10 copy of the same objects. If you examine the id() of the list's elements, for example by id(scores[3]), you can see their references are the same. If you want to have different objects in your list, you should use something like: scores = [[0,0] for i in range(10)]
Related
I was trying to solve the 3Sum problem in leetcode. but I observed python lists behaving different during the end of loop statement.
def threeSum(nums):
n=len(nums)
sum = {}
result = []
for i in range(n):
for j in range(i+1,n):
if i != j:
key = nums[i]+nums[j]
if key not in sum:
sum[key] = [nums[i],nums[j]]
for i in range(n):
if -nums[i] in sum:
temp = sum[-nums[i]]
temp.append(nums[i])
if(len(temp)<=3):
result.append(temp)
print(result)
print("at the end of loop")
print(result)
return "result printed"
nums = [-1,0,1,2,-1,-4]
print(threeSum(nums))
For the above function I got the output as
[[-1, 2, -1]]
[[-1, 2, -1], [-1, 1, 0]]
[[-1, 2, -1], [-1, 1, 0], [-1, 0, 1]]
[[-1, 2, -1], [-1, 1, 0], [-1, 0, 1], [-1, -1, 2]]
at the end of loop
[[-1, 2, -1, -1], [-1, 1, 0], [-1, 0, 1], [-1, -1, 2]]
result printed
From the output you can see that during the last iteration of the loop the result List variable contains the value [[-1, 2, -1], [-1, 1, 0], [-1, 0, 1], [-1, -1, 2]] but when I print the same result at the end of the loop it is printed as [[-1, 2, -1, -1], [-1, 1, 0], [-1, 0, 1], [-1, -1, 2]] , the first element in List is changed.
How do you explain this? Am I missing something in the understanding of Python Lists?
P.S : Please ignore the solution of 3Sum problem, I already found another way to solve it, my question is regarding the Python List only
In Python, List is reference value. In your code, you refer to sum[1] 2 times. Both of 2 times return to the same List instance. That's why after the 2nd time, that List instance is appended 1 more number
This behavior is caused by two issues:
if(len(temp)<=3): will prevent printing the final result due to the length constraint
python lists are mutable and they can be modified from different places if the same object is referenced
In your case, at fourth iteration result[0] and temp will reference the same object. This is why result gets modified even it was not apparently touched. It was changed due to the change of temp variable. You can check this using additional prints to highlight current iteration, result and object ids.
for i in range(n):
print(i)
print(result)
if -nums[i] in sum:
temp = sum[-nums[i]]
temp.append(nums[i])
if(len(temp)<=3):
result.append(temp)
print(result)
print(id(result[0]))
print(id(temp))
print("at the end of loop")
print(result)
return "result printed"
This is the problem :
You will be given a list of lists, each sublist will be of length 2 i.e. [[x,y],[p,q],[l,m]..[r,s]] consider its like a martrix of n rows and two columns
a. the first column Y will contain interger values
b. the second column 𝑌𝑠𝑐𝑜𝑟𝑒 will be having float values
Your task is to find the value of 𝑓(𝑌,𝑌𝑠𝑐𝑜𝑟𝑒)=−1∗1𝑛Σ𝑓𝑜𝑟𝑒𝑎𝑐ℎ𝑌,𝑌𝑠𝑐𝑜𝑟𝑒𝑝𝑎𝑖𝑟(𝑌𝑙𝑜𝑔10(𝑌𝑠𝑐𝑜𝑟𝑒)+(1−𝑌)𝑙𝑜𝑔10(1−𝑌𝑠𝑐𝑜𝑟𝑒)) here n is the number of rows in the matrix
Ex:
[[1, 0.4], [0, 0.5], [0, 0.9], [0, 0.3], [0, 0.6], [1, 0.1], [1, 0.9], [1, 0.8]]
output:
0.4243099
−18⋅((1⋅𝑙𝑜𝑔10(0.4)+0⋅𝑙𝑜𝑔10(0.6))+(0⋅𝑙𝑜𝑔10(0.5)+1⋅𝑙𝑜𝑔10(0.5))+...+(1⋅𝑙𝑜𝑔10(0.8)+0⋅𝑙𝑜𝑔10(0.2)))
My code -
def compute_log_loss(A):
Y = len(A)
Ys = len(A[0])
l = 0
for i in range(Y):
for j in range(Ys):
l += A[i]*math.log10(A[j]) + (1-A[i])*math.log10(1-A[j])
loss=(-1*l)/Y
print(loss)
A = [[1, 0.4], [0, 0.5], [0, 0.9], [0, 0.3], [0, 0.6], [1, 0.1], [1, 0.9], [1, 0.8]]
compute_log_loss(A)```
Im getting the following error :
TypeError Traceback (most recent call last)
<ipython-input-97-bd3b5244f95b> in <module>
17 print(loss)
18 A = [[1, 0.4], [0, 0.5], [0, 0.9], [0, 0.3], [0, 0.6], [1, 0.1], [1, 0.9], [1, 0.8]]
---> 19 compute_log_loss(A)
<ipython-input-97-bd3b5244f95b> in compute_log_loss(A)
13 for i in range(Y):
14 for j in range(Ys):
---> 15 l += A[i]*math.log10(A[j]) + (1-A[i])*math.log10(1-A[j])
16 loss=(-1*l)/Y
17 print(loss)
TypeError: must be real number, not list
A[i] is a list not an single element.
A = [[1, 0.4], [0, 0.5], [0, 0.9], [0, 0.3], [0, 0.6], [1, 0.1], [1, 0.9], [1, 0.8]]
A[0] =[1, 0.4]
A[0][0] =1
A[0][1] =0.4
I'm using Python and Gurobi and I'm having difficulty on how to optimal variable solutions to query a dictionary.
my_dict = {(i, j) : func(Z) for i in I for j in J}
my_dict results to be like this:
{(15687, 'B'): [[7, 0, 0, 0], [0, 7, 0, 0], [0, 0, 7, 0], [0, 0, 0, 7]],
...
(18906, 'C'): [[4, 0, 0, 3], [3, 0, 0, 3], [4, 0, 0, 0], [3, 0, 0, 0]}
Moreover I have a binary variable x[i, j, z] and an assignment constraint:
assignment = m.addConstrs((quicksum(x[i, j, z]
for z in range(len(my_dict[i, j]))) == 1
for i in I for j in J), "assignment")
Supposing I obtain as optimal solution variables
x[15687,'B',0] 1.000000
x[18906,'C',2] 1.000000
Is there a way to retrieve the sublist of my_dict corresponding to the "z" index?
(For instance, if my solution is x[18906,'C',2] 1.000000 then z = 2 and I want to obtain the sublist [4, 0, 0, 0])
Your code is not really a nice minimal example to work with, so it's hard to post valid code.
The general problem does not look that tough.
If your original dict looks like:
{(15687, 'B'): [[7, 0, 0, 0], [0, 7, 0, 0], [0, 0, 7, 0], [0, 0, 0, 7]],
...
(18906, 'C'): [[4, 0, 0, 3], [3, 0, 0, 3], [4, 0, 0, 0], [3, 0, 0, 0]}
and your solution is my_dict_opt, probably something like this should do (python3):
import numpy as np # easy fp-math comparison
sublists = []
for key, val in my_dict.items():
n_vars = len(val) # my assumption
for i in range(n_vars):
if np.isclose(my_dict_opt[key + tuple([i])].X, 1.0): # depends on your dict if .X is needed
sublists.append(my_dict[key][i])
Because of the dicts, the order of elements in sublists is not defined and this should only be a prototype as it's not really clear to me how those dicts are in use for you.
If there is a numpy array that is a list of 2d arrays, is there more efficient way than calling the mean function twice?
z = np.array([[[0, 0, 0],
[10, 10, 10]],
[[0, 0, 0],
[5, 5, 5]],
[[0, 0, 0],
[2, 2, 2]]])
print(z.mean(axis=2).mean(axis=1))
>[ 5. 2.5 1. ]
I have a list whose size is a multiple of 16. What I want to do is go through the list and get 16 elements and create a list from those values, and then store those values somewhere. After that I can either ignore them or remove them from the list, and continue this process until the bigger list is empty. What I was trying to do was to go through the list, and keep a counter of some sort to keep track of the number of elements that have been appended to the list. However, I have been stuck from there. Any ideas on how to accomplish on what I am trying to do? Any ideas would be greatly appreciated.
lst = [[1, 4, 0], [2, 4, 0], [3, 4, 0], [4, 4, 0], [1, 3, 0], [2, 3, 0], [3, 3, 0], [4, 3, 0], [1, 2, 0], [2, 2, 0], [3, 2, 0], [4, 2, 0], [1, 1, 0], [2, 1, 0], [3, 1, 0], [4, 1, 0],[1, 4, 0], [2, 4, 0], [3, 4, 0], [4, 4, 0], [1, 3, 0], [2, 3, 0], [3, 3, 0], [4, 3, 0], [1, 2, 0], [2, 2, 0], [3, 2, 0], [4, 2, 0], [1, 1, 0], [2, 1, 0], [3, 1, 0], [4, 1, 0]]
If I understand you correctly, you start with a list of size n, where n % 16 == 0. You want to end with n/16 lists of size 16. You can accomplish this pretty easily with a double for loop. The outer loop should go for n/16 iterations. the inner loop should go for 16 iterations. The outer loop creates a new list with each iteration. the inner loop takes elements from the original list and appends them to the newly created list.
Thank you for taking the time to respond to my question. After clicking on random links on the right hand side I came to answer that did exactly what I needed to happen.
Here is the solution to my problem:
[input[i:i+n] for i in range(0, len(input), n)]
The solution above goes through input and creates a list of size n.