2 dimensions list (array?) in python - python

I have to create 2 functions that involve a 2 dimension list in order to make a grid for a basic Python game :
The first function must take in parameter an int n and return a list of 2 dimensions with n columns and n lines with all values to 0.
The second one must take a 2 dimension list in parameter and print the grid but return nothing.
Here is what I came with:
def twoDList(x, y):
arr = [[x for x in range(6)] for y in range(6)] # x = height and y = width
return arr
def displayGrid(arr):
for i in range(0, 5):
print(arr[i][i])
Could you please help me to improve the code regarding the instructions and help me to understand how to display the whole grid with the code please?

Here are 2 methods using no 3rd party libraries.
One simple way to create a 2D array is to keep appending an array to an array:
for x in range(10): #width
for y in range(10): #height
a.append(y) #you can also append other data is you want it to be empty, this just makes it 0-9
arr.append(a) #add the 1-9
a = [] #clear the inner array
Here, I re-created the same array (a) 10 times, so it's kind of inefficient, but the point is that you can use the same structure with custom data input to make your own 2D array.
Another way to get the exact same 2D array is list comprehension
arr = [[x for x in range(10)] for y in range(10)]
This is probably what you were trying to do with the code you provided, which is, as mentioned in the comments, syntactically incorrect.
To print, just tweak the code you have to have 2 loops: one for x and one for y:
for x in range(5):
for y in range(5):
print(arr[x][y])

I still see erros in your code:
In your first function, since x,y are your inputs, you want to USE them in your list comprehension. You're not using them in your code
def twoDList(x, y):
arr = [[x for x in range(6)] for y in range(6)] # x = height and y = width
return arr
In your example, no matter what the value of x or y is, you're getting a 6x6 grid. You want to use x and y and replace the fixed values you have over there (HINT: change your '6').
Won't do that for you,
In your print function, you might want to use two variables, once per each dimension, to use as indexes.
Also, don't use fixed values in here, get them from your input (i'm guessing this is homework, so won't put the whole code)
def displayGrid(arr):
for i in range(0, 5):
for j in range(0, 5):
print(arr[i][j])

Related

Suggestions for storing outputs of a nested forloop?

I am trying to write a function in python that gives all possible combinations of three variable inputs that can be of size 1-4. I have written a nested forloop that I believe gives all possible combinations, but I am struggling to store the output in a single 1D array. I don't know if I have to store it as a 3D array and compress it maybe? Here is the code I have:
import numpy as np
def test(x,y,z):
len1 = len(x)
len2 = len(y)
len3 = len(z)
lentot = len1*len2*len3
codons = np.empty((1,lentot))
for i in range(len1):
for j in range(len2):
for k in range(len3):
codons[] = np.array([x[i],y[j],z[k]])
return codons
Basically, I a cannot figure out what to put in the bracket on the second to last line to get my output to store as a 1D array. I don't even know if it is possible. I tried using itertools.product to perform this for me, but the output is stored as a single element, not an array (each line being its own element). For my application it is important that I can pass this output through another function, so I need it to be an array of strings.
You can append them to a list and then convert it to an array at the end.
def test(x, y, z):
codon_list = []
for i in x:
for j in y:
for k in z:
codon_list.append([i, j, k])
codons = np.array(codon_list)
Using the combinations function from itertools itertools.combinations([x, y, z], 3) seems to be the easiest way.
You can use list comprehension to make your life easier:
def test(x,y,z):
codons = np.array([[i,j,k] for i in x for j in y for k in z])
return codons

Whhat is the meaning of given below code?

The question is to take 4 integers as input entered in separate lines.
ex:=
1
1
1
2
The below code does the required thing. I am trying to understand its working part.
x,y,z,n=[int(input()) for _ in range(4)]
welcome!
This code is the equivalent of
x = int(input())
y = int(input())
z = int(input())
n = int(input())
The input() function reads an input from the user and the int tries to transform it to an integer, which is assigned to each variable (x,y, z and n).
The code can be also written as:
numbers = []
for i in range(4): # Loop 4 times
numbers[i] = int(input())
x = numbers[0]
y = numbers[1]
z = numbers[2]
n = numbers[3]
Which is more similar to the form you provided. But the author uses two python features that makes the code smaller (and more expressive). I'll explain both:
List Comprehensions
Lot of times during programming, you will be whiling to execute a command several times and get the results into an list, or for example, map values from one list to other. In this case, you would have something like this:
numbers_til_5 = [0,1,2,3,4,5]
squares_til_5 = []
for n in numbers_til_5:
squares_til_5.append(n*n)
With the List Comprehension syntaxe, we could do:
sqaures_til_5 = [ n*n for n in numbers_til_5]
The other feature is:
Destructuring
This is a feature that allows you to get elements of a list in one single statement.
In the example we have this:
x = numbers[0]
y = numbers[1]
z = numbers[2]
n = numbers[3]
Which could be replaced by x,y,z,n = numbers.
Another form interesting, is when you care only for the first arguments, for example:
first = numbers[0]
rest = numbers[1:] # This get all elements starting from the first
could be written as first, *rest = numbers.
I hope I was able to make it clear.
for _ in range(4) repeats int(input()) 4 times, so the brackets contain now the first four inputs [1, 1, 1, 2].
In Python you can assign multiple variables at one time, so x,y,z and n will be assigned to the corresponding values of the bracket.
For better understanding, you could extract the individial parts like this:
x = int(input())
y = int(input())
z = int(input())
n = int(input())
It is running a loop to input values as integers and feeding those values to the variable x,y,z,n in that sequence. range(n) runs the loop for a range 0-n (in this case, 4 times). _ is used to denote "anything" while running the loop.

Adding a list to itself after addition to each value

I have a list of integers that follows a particular pattern, it's complex but for example say:
x = [0,2,4,6,8]
I'd like to extend the list with 9 more copies of itself, but add a constant value that linearly scales each time. E.g. if
constant = 10
loop = 9
Then the 2nd extension would result in:
x_new = [0,2,4,6,8,10,12,14,16,18]
So I think I want a loop that iterates through x and extends the array by x[i]+constant, loop number of times?
for i in range(loop):
for j in range(len(x)):
x_new = x.extend((x[j]+constant)*i)
Or perhaps this can be easily done through list comprehension? My actual list is ~3000 long and I'll be doing it a few times with different values of loop and constant.
Yes, list comprehension should work:
x_new = [ e + constant * i for i in range(loop+1) for e in x ]
I just did some work on above question, this code can be useful for above question.
x=[0,2,4,6,8]
y=x[4]
i=0
j=0
while(i<9):
z=range(y+2,y+12,2)
x.extend(z)
print x
y=y+10
i=i+1

How is this 2D array being sized by FOR loops?

Question background:
This is the first piece of Python code I've looked at and as such I'm assuming that my thread title is correct in explaining what this code is actually trying to achieve i.e setting a 2D array.
The code:
The code I'm looking at sets the size of a 2D array based on two for loops:
n = len(sentences)
values = [[0 for x in xrange(n)] for x in xrange(n)]
for i in range(0, n):
for j in range(0, n):
values[i][j] = self.sentences_intersection(sentences[i], sentences[j])
I could understand it if each side of the array was set with using the length property of the sentences variable, unless this is in effect what xrange is doing by using the loop size based on the length?
Any helping with explaing how the array is being set would be great.
This code is actually a bit redundant.
Firstly you need to realize that values is not an array, it is a list. A list is a dynamically sized one-dimensional structure.
The second line of the code uses a nested list comprehension to create one list of size n, each element of which is itself a list consisting of n zeros.
The second loop goes through this list of lists, and sets each element according to whatever sentences_intersection does.
The reason this is redundant is because lists don't need to be pre-allocated. Rather than doing two separate iterations, really the author should just be building up the lists with the correct values, then appending them.
This would be better:
n = len(sentences)
values = []
for i in range(0, n):
inner = []
for j in range(0, n):
inner.append(self.sentences_intersection(sentences[i], sentences[j]))
values.append(inner)
but you could actually do the whole thing in the list comprehension if you wanted:
values = [[self.sentences_intersection(sentences[i], sentences[j]) for i in xrange(n)] for j in xrange(n)]

2D Array Unintended Assignment Bug

I want to create a 2D array, like so:
grid[y][x]
So that there are y amount of rows and x amount of columns.
Below is the way I did it, but I when I tried to assign the (0,0) of the array to contain the value '2', the code assigned the first value of each subarray to '2'.
Why is this happening? How should I pythonically instantiate a 2D array?
n = 4
x=0
y=0
grid = [[None]*n]*n
print grid
grid[y][x]='Here'
print grid
when you use * you create multiple references, it does not copy the data
so when you modify the first line to
[here,none,none,none]
you actually change all lines.
solution
[[None for i in range(n)] for j in range(n)]
Edit (from other post) Since only the lists are mutable (can change in place) you can also do
[[None]*n for j in range(n)].
Each of the rows are then still unique. If the None object could be changed in place this would not work.
grid = [[None]*n for i in range(n)]

Categories