Two dimensional array in python - python

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']]

Related

Iterating over numpy array and access the values

I want to iterate over a numpy array and do some calculations on the values. However, things are not as expected. To show what I mean, I simply wrote this code to read values from a numpy array and move them to another list.
a = array([1,2,1]).reshape(-1, 1)
u = []
for i in np.nditer(a):
print(i)
u.append(i)
print(u)
According to tutorial, nditer points to elements and as print(i) shows, i is the value. However, when I append that i to an array, the array doesn't store the value. The expected output is u = [1, 2, 1] but the output of the code is
1
2
1
[array(1), array(2), array(1)]
What does array(1) mean exactly and how can I fix that?
P.S: I know that with .tolist() I can convert a numpy array to a standard array. However, in that code, I want to iterate over numpy elements.
As already explained in your previous question, numpy.nditer yields numpy arrays. What is shown by print is only the representation of the object, not the content or type of the object (e.g., 1 and '1' have the same representation, not the same type).
import numpy as np
a = np.array([1,2,1]).reshape(-1, 1)
type(next(np.nditer(a)))
# numpy.ndarray
You just have a zero-dimensional array:
np.array(1).shape
# ()
There is no need to use numpy.nditer here. If you really want to iterate over the rows of your array with single column (and not use tolist), use:
u = []
for i in a[:,0]:
u.append(i)
u
# [1, 2, 1]
numpy.nditer actually returns a numpy array. If you want the actual value of this item, you can use the built in item() function:
a = array([1,2,1]).reshape(-1, 1)
u = []
for i in np.nditer(a):
u.append(i.item())
print(u)
A pure python equivalent of what's happening with your append is:
In [75]: alist = []
...: x = [0]
...: for i in range(3):
...: x[0] = i
...: print(x)
...: alist.append(x)
[0]
[1]
[2]
In [76]: alist
Out[76]: [[2], [2], [2]]
In [77]: x
Out[77]: [2]
x is modified in each loop, but only a reference is saved. The result is that all elements of the list are the same object, and display its last value.

Excluding elements from an old array and creating a new array

I have an array that has 3 different values, I want to create a new array that has only the values that are smaller that 12 (for example).
import array as arr
numbers = arr.array([10,12, 12, 13])
numbers.remove(12)
numbers.remove(13)
print(numbers)
I don't know how to add them in a new array
There are a few ways to solve this problem. Here's how I would go about it.
import array as arr
numbers = arr.array('i', [10,12,12,13])
new_nums = arr.array('i', [i for i in numbers if i<12])
You can also use the pop() method, like so:
new_nums = arr.array('i', [numbers.pop(i) for i,val in enumerate(numbers) if val<12])
Alternatively, you can just use list comprehension on a Python list, like this:
new_nums = [i for i in numbers if i<12]
Hope this helps!
numbers = [10,12,13,14]
newarr = []
for i in numbers:
if i<12:
newarr.append(i)
print(newarr)
Use a python list and iterate over the previous list(Use list, not an array), check for the required condition and add(append) the results to a new list.
Assumption:
you want only unique elements from the initial list
the elements should be less than 12
Code:
initial_list = [10, 12, 12, 13]
new_list = [i for i in list(set(initial_list)) if i<12]
print(new_list)
Output:
[10]
Explanation:
The above code first creates a set of unique elements from the initial list. Then it selects the only items that meet the condition i<12 using a list comprehension.
N.B.: If you are bound to use array module, #Praveenkumar's answer is the way to use.
You can do the below if you want to stick with array only (I don't know why you want to do that). array and list in python are different things.
import array as arr
numbers = arr.array('i', [10,11, 12, 13])
print(arr.array('i', filter(lambda x : x < 12, numbers)))

Find all the row indices of a set of elements in a 2D Array

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.

Converting two lists into a matrix

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)

2D array of lists in python

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)

Categories

Resources