I am trying to create a 2d matrix so that each cell contains a list of strings.
Matrix dimensions are known before the creation and I need to have access to any element from the beginning (not populating a matrix dynamically). I think some kind of pre-allocation of space is needed.
For example, I would like to have a 2X2 matrix:
[['A','B'] ['C'];
['d'] ['e','f','f']]
with support of traditional matrix access operations, like
(Matrix[2][2]).extend('d')
or
tmp = Matrix[2][2]
tmp.extend('d')
Matrix[2][2] = tmp
to manipulate with cells content.
How to accomplish it in python?
Just as you wrote it:
>>> matrix = [["str1", "str2"], ["str3"], ["str4", "str5"]]
>>> matrix
[['str1', 'str2'], ['str3'], ['str4', 'str5']]
>>> matrix[0][1]
'str2'
>>> matrix[0][1] += "someText"
>>> matrix
[['str1', 'str2someText'], ['str3'], ['str4', 'str5']]
>>> matrix[0].extend(["str6"])
>>> matrix[0]
['str1', 'str2someText', 'str6']
Just think about 2D matrix as list of the lists. Other operations also work fine, for example,
>>> matrix[0].append('value')
>>> matrix[0]
[0, 0, 0, 0, 0, 'value']
>>> matrix[0].pop()
'value'
>>>
You can either do it with the basic:
matrix = [
[["s1","s2"], ["s3"]],
[["s4"], ["s5"]]
]
or you can do it very genericially
from collections import defaultdict
m = defaultdict(lambda : defaultdict(list))
m[0][0].append('s1')
In the defaultdict case you have a arbitrary matrix that you can use, any size and all the elements are arrays, to be manipulated accordingly.
First of all, what you describe is actually a 3 dimensional matrix since each 'cell' also has a dimension whose kth element of the jth column of the ith row could be accessed via matrix[i][j][k].
Regardless, if you'd like to preallocate a 2X2 matrix with every cell initialized to an empty list, this function will do it for you:
def alloc_matrix2d(W, H):
""" Pre-allocate a 2D matrix of empty lists. """
return [ [ [] for i in range(W) ] for j in range(H) ]
However you might think it's not working because I noticed that you said that you would like to have a 2X2 matrix like this:
[
[
['A','B'], ['C']
],
[
['d'], ['e','f','f']
]
]
and be able to use "traditional matrix access operations" to do this to it:
(Matrix[2][2]).extend('d')
Problem is that won't work even for the matrix shown and still wouldn't for one preallocated to 2X2 since both the row and column dimensions are out of range in either case. In Python all sequences are indexed from zero, so valid indices for a matrix with two rows of two elements each are [0][0], [0][1], [1][0], and [1][1] (ignoring possible negative indices which have a special meaning in Python). So using Matrix[2][2] is an attempt to access the third column of the third row of the matrix which don't exist and wouldn't even in a preallocated one with dimensions of 2X2.
Everything would be fine if you changed that statement to something like this using one of the valid pairs of index values (and with unnecessary parentheses removed):
Matrix[1][1].extend('d')
since it would not raise an IndexError and instead would result in the 2X2 matrix becoming:
[
[
['A', 'B'], ['C']
],
[
['d'], ['e', 'f', 'f', 'd']
]
]
Bonus Utility
You didn't ask for one, but here's a handy function I wrote to help printing out arbitrarily sized 2D matrices of any type (represented as nested lists):
def repr_matrix2d(name, matrix):
lines = ['{} = ['.format(name)]
rows = []
for row in range(len(matrix)):
itemreprs = [repr(matrix[row][col]) for col in range(len(matrix[row]))]
rows.append('\n [\n {}\n ]'.format(', '.join(itemreprs)))
lines.append('{}\n]'.format(','.join(rows)))
return ''.join(lines)
Hope this helps.
One option is to write your own class, where you overload the [] operator. Take a look for that in here: http://www.penzilla.net/tutorials/python/classes/ .
Acessing a 2d elment in 1d is y * rowSize + x. Extending the elements by writing an append function, which would use append rowSize times.
If you want to create a 2d matrix and you need to preallocate than, you could do the following:
x,y = 3,3
A = [ [None]*x for i in range(y) ]
You can replace None with the value you want. And you can use .extend to add additional values.
Here's some minimal example that extends 2d list of lists:
my_list = [ [ [1] for x in range(4) ] for j in range(2) ]
print('initial list is ', my_list)
my_list[0][1].append(9)
print('list after extension is ', my_list)
and the results are
initial list is [[[1], [1], [1], [1]], [[1], [1], [1], [1]]]
list after extension is [[[1], [1, 9], [1], [1]], [[1], [1], [1], [1]]]
Hey guys not sure if this is helpful or not but this is how I generated a 2d list with python3.4 hope this is helpful
list=[]
list1=[]
list2=[]
list3=[]
answer1='yes'
answer2='yes'
answer3='yes'
while answer1=='yes':
item1=input("Please input a list element for your first list:")
answer1=input("Do you want to continue:")
list1.append(item1)
while answer2=='yes':
item2=input("Please input a list element for your second list:")
answer2=input("Do you want to continue:")
list2.append(item2)
while answer3=='yes':
item3=input("Please input a list element for your third list:")
answer3=input("Do you want to continue:")
list3.append(item3)
list.append(list1)
list.append(list2)
list.append(list3)
print(list)
Related
So I am trying to make a hash function that put an element k into a 2D array based on it's mod. For this example the size of the outer array is 4. So to start out the hash table I want it to be a 2D array that has the size of the outer array to be 4. Then there will be 4 empty arrays inside the outer array. Like so...
n = 4
A = [[]]* n
Which is [ [], [], [], [] ] So when I use the hash function like this hash(A, 2) it should output this [ [], [], [2], [] ] based on this code below...
def hash(A, k):
idx = k % 4
for i in range(len(A)):
for j in range(len(A[i])):
if i == idx:
print(A[i][j])
A[i][j] = A[i][j].append(k)
So the problem is that it outputs this [ [], [], [], [] ] and not this [ [], [], [2], [] ].
I have tried...
def hash(A, k):
idx = k % 4
A[idx].append(k)
but this only outputs [[2], [2], [2], [2]] which is not what I want.
How do I make my hash function give me this output [ [], [], [2], [] ]?
(P.S. I know it's a lot better to simply just make an array of linked lists. I am doing this for a better understanding of hash table if they were implemented with arrays and to get a better understanding of 2D arrays.)
The second solution doesn't work because of the behavior of the multiplication operator for lists. When someone writes A = [[]]*n, all of the n inner lists are, in fact, the same list (the same location in memory), so changing one of them changes every one of them. If A is created as A = [[] for _ in range(n)] instead, these inner lists aren't the same object anymore, and they'll work as you intended.
The first solution doesn't work for several reasons; the most immediate one is that len(A[i]) equals 0 at the start of the loop for every i, so the function will skip past it every time (and never increment it).
Even if you correct it, A[i][j] is not a list, so it would give you an error when you call .append() on it. The lists are A[i], and you'll want to append to them.
Not only that, but the first solution is subject to the same problem as the second one.
(Source:https://docs.python.org/3/library/stdtypes.html#common-sequence-operations, notes 2 and 3)
I created a large array that is similar to this:
data = [ [1,2,3], [0,1,3],[1,5,3]]
How can I make it so my new array sums up each individual array as shown?
data = [ [6],[4],[9] ]
List comprehensions are good for this:
[[sum(x)] for x in data] # [[6], [4], [9]]
List comprehensions provide a concise way to create lists. Common
applications are to make new lists where each element is the result of
some operations applied to each member of another sequence or
iterable, or to create a subsequence of those elements that satisfy a
certain condition.
You're wanting to make a new list where each element is the result of some operations (a sum in this case) applied to each member of another sequence or iterable (your list of lists).
This works.
a = [ [1,2,3], [0,1,3],[1,5,3]]
b = []
for i in a:
sum = 0
for j in i:
sum+=j
b.append([sum])
print(b)
I have a particular list of numbers(item_list) for which i need all the row indices associated inside a 2D array (C). Please find the code below :
# Sample code
item_list = [1, 2, 3]
C= [[0 for x in range(5)] for x in range(5)]
C[0][:]=[1,5,3,25,30]
C[1][:]=[7,9,15,2,45]
C[2][:]=[2,9,15,78,98]
C[3][:]=[3,90,15,1,98]
C[4][:]=[12,19,25,3,8]
rind=[]
for item in item_list:
v=[i for i in range(len(C)) for j in range (len(C[i])) if C[i][j]==item ]
r_ind.append(v)
My 2D array size is ~ 7M *4, could anyone help me make this faster?
For starters:
rind = [[i for i in range(len(C)) if item in C[i]]
for item in item_list]
The crucial change here is the use of in which should be faster than your manual check.
This also means you won't get the same i multiple times in sublists in the output if a number appears multiple times in a sublist in the input, which I assume is what you really want.
I'll try to be as clear as possible, and I'll start by explaining why I want to transform two arrays into a matrix.
To plot the performance of a portfolio vs an market index I need a data structure like in this format:
[[portfolio_value1, index_value1]
[portfolio_value2, index_value2]]
But I have the the data as two separate 1-D arrays:
portfolio = [portfolio_value1, portfolio_value2, ...]
index = [index_value1, index_value2, ...]
So how do I transform the second scenario into the first. I've tried np.insert to add the second array to a test matrix I had in a python shell, my problem was to transpose the first array into a single column matrix.
Any help on how to achieve this without an imperative loop would be great.
The standard numpy function for what you want is np.column_stack:
>>> np.column_stack(([1, 2, 3], [4, 5, 6]))
array([[1, 4],
[2, 5],
[3, 6]])
So with your portfolio and index arrays, doing
np.column_stack((portfolio, index))
would yield something like:
[[portfolio_value1, index_value1],
[portfolio_value2, index_value2],
[portfolio_value3, index_value3],
...]
Assuming lengths of portfolio and index are the same:
matrix = []
for i in range(len(portfolio)):
matrix.append([portfolio[i], index[i]])
Or a one-liner using list comprehension:
matrix2 = [[portfolio[i], index[i]] for i in range(len(portfolio))]
You can use np.c_
np.c_[[1,2,3], [4,5,6]]
It will give you:
np.array([[1,4], [2,5], [3,6]])
Simple you can try this
a=list(zip(portfolio, index))
You can try the below incase you cant use numpy
Zip wont work for lists of diff length and it returns a tuple and not a list
class Matrix:
def __init__(self, list1, list2):
self.list1 = list1
self.list2 = list2
def get_mix(self,list1,list2):
matrix = []
for elem_one in list1:
for elem_two in list2 :
if elem_two:
last_elem = elem_two
matrix.append([elem_one,elem_two])
else :
matrix.append([elem_one,last_elem])
return matrix
def get_matrix(self):
returnlist = []
if len(self.list1) == len(self.list2):
for elem_one in self.list1:
for elem_two in self.list2:
returnlist.append([elem_one,elem_two])
return returnlist
elif len(self.list1) > len(self.list2):
return self.get_mix(self.list1,self.list2)
elif len(self.list1) < len(self.topplist2ings):
return self.get_mix(self.list2,self.list1)
I want to know how to declare a two dimensional array in Python.
arr = [[]]
arr[0].append("aa1")
arr[0].append("aa2")
arr[1].append("bb1")
arr[1].append("bb2")
arr[1].append("bb3")
The first two assignments work fine. But when I try to do, arr[1].append("bb1"), I get the following error:
IndexError: list index out of range.
Am I doing anything silly in trying to declare the 2-D array?
Edit:
but I do not know the number of elements in the array (both rows and columns).
You do not "declare" arrays or anything else in python. You simply assign to a (new) variable. If you want a multidimensional array, simply add a new array as an array element.
arr = []
arr.append([])
arr[0].append('aa1')
arr[0].append('aa2')
or
arr = []
arr.append(['aa1', 'aa2'])
There aren't multidimensional arrays as such in Python, what you have is a list containing other lists.
>>> arr = [[]]
>>> len(arr)
1
What you have done is declare a list containing a single list. So arr[0] contains a list but arr[1] is not defined.
You can define a list containing two lists as follows:
arr = [[],[]]
Or to define a longer list you could use:
>>> arr = [[] for _ in range(5)]
>>> arr
[[], [], [], [], []]
What you shouldn't do is this:
arr = [[]] * 3
As this puts the same list in all three places in the container list:
>>> arr[0].append('test')
>>> arr
[['test'], ['test'], ['test']]
What you're using here are not arrays, but lists (of lists).
If you want multidimensional arrays in Python, you can use Numpy arrays. You'd need to know the shape in advance.
For example:
import numpy as np
arr = np.empty((3, 2), dtype=object)
arr[0, 1] = 'abc'
You try to append to second element in array, but it does not exist.
Create it.
arr = [[]]
arr[0].append("aa1")
arr[0].append("aa2")
arr.append([])
arr[1].append("bb1")
arr[1].append("bb2")
arr[1].append("bb3")
We can create multidimensional array dynamically as follows,
Create 2 variables to read x and y from standard input:
print("Enter the value of x: ")
x=int(input())
print("Enter the value of y: ")
y=int(input())
Create an array of list with initial values filled with 0 or anything using the following code
z=[[0 for row in range(0,x)] for col in range(0,y)]
creates number of rows and columns for your array data.
Read data from standard input:
for i in range(x):
for j in range(y):
z[i][j]=input()
Display the Result:
for i in range(x):
for j in range(y):
print(z[i][j],end=' ')
print("\n")
or use another way to display above dynamically created array is,
for row in z:
print(row)
When constructing multi-dimensional lists in Python I usually use something similar to ThiefMaster's solution, but rather than appending items to index 0, then appending items to index 1, etc., I always use index -1 which is automatically the index of the last item in the array.
i.e.
arr = []
arr.append([])
arr[-1].append("aa1")
arr[-1].append("aa2")
arr.append([])
arr[-1].append("bb1")
arr[-1].append("bb2")
arr[-1].append("bb3")
will produce the 2D-array (actually a list of lists) you're after.
You can first append elements to the initialized array and then for convenience, you can convert it into a numpy array.
import numpy as np
a = [] # declare null array
a.append(['aa1']) # append elements
a.append(['aa2'])
a.append(['aa3'])
print(a)
a_np = np.asarray(a) # convert to numpy array
print(a_np)
a = [[] for index in range(1, n)]
For compititve programming
1) For input the value in an 2D-Array
row=input()
main_list=[]
for i in range(0,row):
temp_list=map(int,raw_input().split(" "))
main_list.append(temp_list)
2) For displaying 2D Array
for i in range(0,row):
for j in range(0,len(main_list[0]):
print main_list[i][j],
print
the above method did not work for me for a for loop, where I wanted to transfer data from a 2D array to a new array under an if the condition. This method would work
a_2d_list = [[1, 2], [3, 4]]
a_2d_list.append([5, 6])
print(a_2d_list)
OUTPUT - [[1, 2], [3, 4], [5, 6]]
x=3#rows
y=3#columns
a=[]#create an empty list first
for i in range(x):
a.append([0]*y)#And again append empty lists to original list
for j in range(y):
a[i][j]=input("Enter the value")
In my case I had to do this:
for index, user in enumerate(users):
table_body.append([])
table_body[index].append(user.user.id)
table_body[index].append(user.user.username)
Output:
[[1, 'john'], [2, 'bill']]