Unexpected behaviour in list value change - python

I defined this function:
def newMap(dim, n):
tc = [0 for i in range(n)]
return [[tc for _ in range(dim)] for _ in range(dim)]
Which creates a list of lists of zeroes. For example
m = newMap(2,2)
print(m)
returns
[[[0, 0], [0, 0]], [[0, 0], [0, 0]]]
I want to change one os the zeroes to obtain [[[0, 0], [0, 0]], [[0, 0], [0, 0]]] and tried doing so by
m[0][0][0] = 1
which, unexpectedly returns [[[1, 0], [1, 0]], [[1, 0], [1, 0]]] instead of [[[1, 0], [0, 0]], [[0, 0], [0, 0]]].
However, if I defined a = [[[0, 0], [0, 0]], [[0, 0], [0, 0]]], and then do
a[0][0][0] = 1
print(a)
it returns [[[1, 0], [0, 0]], [[0, 0], [0, 0]]], which is what I want.
Why does this happen? Shouldn't the two definitions be equivalent? How can I prevent it from happening in the first case?

Use tc.copy() this should fix it, i tried it and it works:
def newMap(dim, n):
tc = [0 for i in range(n)]
return [[tc.copy() for _ in range(dim)] for _ in range(dim)]
a = newMap(2,2)
a
#[[[0, 0], [0, 0]], [[0, 0], [0, 0]]]
a[0][0][0] = 1
#[[[1, 0], [0, 0]], [[0, 0], [0, 0]]]

Related

List of lists with incremented elements

I've made some generic example of my problem.
I have something like this:
n = 2
test = [[[0,0] for j in range(1)] for k in range(n)]
print(test)
And I get the following output:
[[[0, 0]], [[0, 0]]]
But what I want - as output - is something like that:
[[[0, 0]], [[0, 0],[0, 0]]]
And for n = 3, the output must be:
[[[0, 0]], [[0, 0],[0, 0]], [[0,0],[0,0],[0,0]]]
You can do it by specifying the start argument of range:
[[[0,0] for _ in range(k)] for k in range(1, n+1)]
Output (for n=3):
[[[0, 0]], [[0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]

Python replacing all list elements instead of the indexed list element in for loop

I want to replace the kth element of the kth element of the list.
E.g.,
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]
to
[[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]
BUT python does not seem to want to do that and instead is replacing each value for each element.
I run this:
# Triangle Vertices
V = [[0, 1], [-1, 0], [1, 0]]
# Triangles (indices of V in clockwise direction)
T = [[1, 0, 2]]
# Creating sub-triangles
bary_point = [0, 0.5]
v_list = []
for t in T:
print(t)
for k in range(3):
v_list.append(V)
v_list[k][k] = bary_point # <-- This line
print('v_list: ')
print(v_list)
and it produces this:
v_list:
[[[0, 0.5], [0, 0.5], [0, 0.5]],
[[0, 0.5], [0, 0.5], [0, 0.5]],
[[0, 0.5], [0, 0.5], [0, 0.5]]]
but I want this:
v_list:
[[[0, 0.5], [-1, 0], [1, 0]],
[[0, 1], [0, 0.5], [1, 0]],
[[0, 1], [-1, 0], [0, 0.5]]]
Am I doing something wrong? I am on Python 3.10.0
Thank you.
EDIT Solution:
Change
v_list.append(V)
to
v_list.append(V.copy())
Thank you!
You are appending the same reference to the list V, and when you change v_list[k][k] you are changing V, one solution would be to append a copy of the list, by using V.copy() as argument to append.

Python: Selecting repeated elements (list in a list) and put it in an array? [duplicate]

This question already has answers here:
How do I remove duplicates from a list, while preserving order?
(30 answers)
Closed 2 years ago.
How to make from this:
[[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 1], [1, 0, 1], [1, 0, 1]]
to this?
array([[1, 0, 0],
[1, 0, 1]])
I tried this but it only works with 2 repeated elements. I want it to work for any number of repeated elements.
finalRes = []
for i in range(len(resList)-1):
if resList[i] == resList[i+1]:
finalRes.append(resList[i])
finalRes --> [[1, 0, 0], [1, 0, 0], [1, 0, 1], [1, 0, 1]]
Use itertools.groupby:
from itertools import groupby
lst = [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 1], [1, 0, 1], [1, 0, 1]]
result = [key for key, _ in groupby(lst)]
print(result)
Output
[[1, 0, 0], [1, 0, 1]]
You can use numpy.unique to find the unique elements in the array.
Use:
import numpy as np
arr = [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 1], [1, 0, 1], [1, 0, 1]]
unique_arr = np.unique(arr, axis=0)
print(unique_arr)
This prints:
[[1 0 0]
[1 0 1]]

Generate one-hot vector from a nx1 array of binary labels

I have an array like this:
X = [0,0,1,1,0,0,1,1,1,0,0,0]
I want to create a one-hot encoder vector of nx2
one_hotX = [[1,0],[1,0],[0,1],[0,1],[1,0]...]
Is there an easy way to do this? OneHotEncoder and LabelEncoder don't seem to work.
How about constructing the vector by yourself:
[[0, 1] if i else [1, 0] for i in X]
#[[1, 0],
# [1, 0],
# [0, 1],
# [0, 1],
# [1, 0],
# [1, 0],
# [0, 1],
# [0, 1],
# [0, 1],
# [1, 0],
# [1, 0],
# [1, 0]]
If you are working with numpy, you could do something such as this as well(vectorized approach):
import numpy as np
code = np.array([[1,0],[0,1]])
arrX = np.array(X)
code[arrX]
#array([[1, 0],
# [1, 0],
# [0, 1],
# [0, 1],
# [1, 0],
# [1, 0],
# [0, 1],
# [0, 1],
# [0, 1],
# [1, 0],
# [1, 0],
# [1, 0]])

How do I create many matrices inside a loop statement with python?

I want to create for example n matrices like:
m1 = [[0,0],[0,0]]
m2 = [[0,0],[0,0]]
.
.
mn = [[0,0],[0,0]]
I think that will work for you
res = [[[0 for item3 in range(2)] for item2 in range(2)] for item1 in range(10)]
print res
Output:
[
[[0, 0], [0, 0]],
[[0, 0], [0, 0]],
[[0, 0], [0, 0]],
[[0, 0], [0, 0]],
[[0, 0], [0, 0]],
[[0, 0], [0, 0]],
[[0, 0], [0, 0]],
[[0, 0], [0, 0]],
[[0, 0], [0, 0]],
[[0, 0], [0, 0]]
]
Basically 10(your n value) arrays with 2x2 lists of zeros.

Categories