Let's say we have 2D array foo_arr
:
foo_arr = [[None, None, None, None],
[None, None, None, None],
[None, None, None, None],
[None, None, None, None]]
Now, I want to be able to access the 2D array from both its rows and its columns. For example, I can just do row_0 = foo_arr[0]
, and any changes to foo_arr[0]
will be reflected in row_0
; ie if we do this:
row_0 = foo_arr[0]
foo_arr[0][0] = (0, 0)
# row_0 == [(0, 0), None, None, None]
I also want to be able to do this with columns. For example, I want something like column_0 = [foo_arr[0][0], foo_arr[1][0], foo_arr[2][0], foo_arr[3][0]]
, and when I change foo_arr
(or column_0
), they should each be able to see. An illustration of the desired behaviour:
column_0 = [foo_arr[i][0] for i in range(4)]
foo_arr[0][0] = (0, 0)
foo_arr[1][0] = (0, 1)
# Desired: column_0 == [(0, 0), (0, 1), None, None]
# Actual: column_0 == [None, None, None, None]
Essentially, I'd like this, written in C:
int** foo_arr = malloc(sizeof(int*)*4);
for(int i=0; i<4; i++) {
foo_arr[i] = malloc(sizeof(int)*4);
for(int j=0; j<4; j++) {
foo_arr[i][j] = -1; /* Using -1 here to represent None */
}
}
int* row_0 = foo_arr[0];
int** column_0 = malloc(sizeof(int)*4);
for(int i=0; i<4; i++) {
column_0[i] = &foo_arr[i][0]; /* Yes, technically the same as just doing foo_arr[i] for column 0 */
}
/* Changing the 2D array: */
foo_arr[0][0] = 0;
foo_arr[1][0] = 4;
foo_arr[2][0] = 8;
/* We should have:
*column_0[0] == 0;
*column_0[1] == 4;
*column_0[2] == 8; */
Is it possible to get this behaviour in Python? Does numpy or other packages have this behaviour? edit: I'd like to avoid writing a "wrapper" function that just extracts the column. If I'm processing on columns many times, I don't want to generate a new list that represents a column every time I want to operate on columns.
so you have some super complicated code, but all you really need is a numpy
array :
import numpy as np
# foo_arr = np.array(
# [
# [None, None, None, None],
# [None, None, None, None],
# [None, None, None, None],
# [None, None, None, None]
# ]
# )
# or better:
foo_arr = np.empty((4, 4), dtype=object)
row_0 = foo_arr[0, :]
col_0 = foo_arr[:, 0]
foo_arr[1, 0] = (0, 0)
print(row_0, col_0)
I don't think there is a straight forward way of doing this with 2D+ lists. But with numpy it's trivial:
foo_lst = [[None, None, None, None],
[None, None, None, None],
[None, None, None, None],
[None, None, None, None]]
foo_arr = np.array(foo_lst, dtype=object)
foo_arr[:, 0] = np.arange(4)
Result:
array([[0, None, None, None],
[1, None, None, None],
[2, None, None, None],
[3, None, None, None]], dtype=object)
If you will mainly be dealing with columns of a list
you can consider taking the transpose:
lst2d = [[...], [...], ...]
lst2d_t = [list(col) for col in zip(*lst2d)]
# index the ith "column" like so: lst2d_t[col_no]
But numpy is preferable at this point.
You can create a type which knows where to look for changes:
class ListRef:
def __init__(self, collection, index):
self.collection = collection
self.index = index
def get(self):
return self.collection[self.index]
def __repr__(self):
return str(self.get())
foo_arr = [[None, None, None, None],
[None, None, None, None],
[None, None, None, None],
[None, None, None, None]]
column_0 = [ListRef(foo_arr[i], 0) for i in range(4)]
print(column_0)
foo_arr[0][0] = (0, 0)
foo_arr[1][0] = (0, 1)
print(column_0)
Output:
[None, None, None, None]
[(0, 0), (0, 1), None, None]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.