This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 2 years ago.
I was trying a program in which I declared a 2D array named grid of size 5 x 5 globally in python.
grid = [[0] * 5] * 5
def main():
global grid
n,m = map(int,input().split())
for i in range(n):
li = list(map(int,input().split()))
for j in range(m):
if j < 5:
grid[i][j] = li[j]
print(grid)
if __name__ == "__main__":
main()
Modifying the grid gives a weird answer. For example if the input is :-
2 3
1 2 3
4 5 6
2 rows and 3 columns (n and m)
It gives the following output:-
[[4, 5, 6, 0, 0], [4, 5, 6, 0, 0], [4, 5, 6, 0, 0], [4, 5, 6, 0, 0], [4, 5, 6, 0, 0]]
Even when I remove the line global grid from the main function, output remains the same. What is going on? I want it to update grid according to the input and leave the extra cells untouched i.e value 0. If input is of size 2 x 3 then only the first 2 rows and 3 columns of the grid should be modified according to the input and rest of the elements should remain 0.
You should use:
[[0]*5 for _ in range(5)]
Instead of:
[[0] * 5] * 5
for more information, check this question.
Related
This question already has answers here:
Sum a list of numbers in Python
(26 answers)
Closed last year.
This post was edited and submitted for review last year and failed to reopen the post:
Original close reason(s) were not resolved
For example array [1, 2, 4, 5, 6] it must be 1 + 2 + 4 + 5 + 6. so how is the result in these loops? so look below the script
number = [1, 2, 4, 5, 6]
for x in number:
x + x
print(x)
Just add a += and a new variable like so:
number = [1, 2, 4, 5, 6]
y = 0 #new variable (output variable)
for x in number:
y += x #add = sign here
print(y)
Output:
18
But it would be better to use:
y = sum(number)
print(y)
Output:
18
I have a code:
x = 6
for y in range(x):
print(y)
x -= 2
It gives: 0, 1, 2, 3, 4, 5
I wrongly predicted that it would give either of these 2 results:
0, 0, 0
Since x goes from 6 to 4 to 2 to 0, there will only be 3 y printed. Also, to my understanding, after each loop, it goes back to the for loop statement, thus resets the range() completely and now every y is 0. I ran the code on PythonTutor and the pointer also seemed to go back to the loop statement after each loop.
0, 1, 2
Since x goes from 6 to 4 to 2 to 0, there will only be 3 y printed. I thought it might be possible that while y takes on the value of the original range (i.e. 6), it would be limited by each new x and thus only have 3 y printed.
Possibility 1 was the most intuitive (albeit wrong) for me and I am not sure how to go about understanding why the answer is as such.
The instance of range produced by range(x) uses the value of x at the time range is called. It does not repeatedly check the value of x each time you need a new value from the range. Your code is effectively the same as
x = 6
for y in [0, 1, 2, 3, 4, 5]:
print(y)
x -= 2
Nothing you do to x has any effect on the range object being iterated.
The range() call creates a range object from x at the start of the loop. Changing x after this has no effect on the range object that is being used to iterate.
If you want to be able to change how many iterations you make in a loop, you probably want to look at using while.
Try this:
# Firstly you assign 6 to the variable x
x = 6
# 'y' will now be assigned to the numbers [0, 1, 2, 3, 4, 5, 6] because the range is 'x' which is 6.
# by printing 'x' it will execute [0, 1, 2, 3, 4, 5, 6] but since x is 'x -2' which is the same as '6 - 2' it will print out the number 6 and -2 until it gets to the range which is -6. the output will be 6 numbers [6, 4, 2, 0, -2, -4]
for y in range(x):
print(x)
x = x - 2
# i am showing you a way of making it give you your expected output [6, 4, 2, 0, -2, -4]
I'm new to both algorithms AND programming.
As an intro to the MERGE algorithms the chapter introduces first the MERGE algorithm by itself. It merges and sorts an array consisting of 2 sorted sub-arrays.
I did the pseudocode on paper according to the book:
Source: "Introduction to Algorithms
Third Edition" Thomas H. Cormen Charles E. Leiserson Ronald L. Rivest Clifford Stein
Since I am implementing it in python3 I had to change some lines given that indexing in python starts at 0 unlike in the pseudocode example of the book.
Keep in mind that the input is one array that contains 2 SORTED sub-arrays which are then merged and sorted, and returned. I kept the prints in my code, so you can see my checks...
#!/anaconda3/bin/python3
import math
import argparse
# For now only MERGE slides ch 2 -- Im defining p q and r WITHIN the function
# But for MERGE_SORT p,q and r are defined as parameters!
def merge(ar):
'''
Takes as input an array. This array consists of 2 subarrays that ARE ALLREADY sorted
(small to large). When splitting the array into half, the left
part will be longer by one if not divisible by 2. These subarrays will be
called left and right. Each of the subarrays must already be sorted. Merge() then
merges these sorted arrays into one big sorted array. The sorted array is returned.
'''
print(ar)
p=0 # for now defining always as 0
if len(ar)%2==0:
q=len(ar)//2-1 # because indexing starts from ZERO in py
else:
q=len(ar)//2 # left sub array will be 1 item longer
r=len(ar)-1 # again -1 because indexing starts from ZERO in py
print('p', p, 'q', q, 'r', r)
# lets see if n1 and n2 check out
n_1 = q-p+1 # lenght of left subarray
n_2 = r-q # lenght of right subarray
print('n1 is: ', n_1)
print('n2 is: ', n_2)
left = [0]*(n_1+1) # initiating zero list of lenght n1
right=[0]*(n_2+1)
print(left, len(left))
print(right, len(right))
# filling left and right
for i in range(n_1):# because last value will always be infinity
left[i] = ar[p+i]
for j in range(n_2):
right[j] = ar[q+j+1]
#print(ar[q+j+1])
#print(right[j])
# inserting infinity at last index for each subarray
left[n_1]=math.inf
right[n_2]=math.inf
print(left)
print(right)
# merging: initiating indexes at 0
i=0
j=0
print('p', p)
print('r', r)
for k in range(p,r):
if left[i] <= right[j]:
ar[k]=left[i]
# increase i
i += 1
else:
ar[k]=right[j]
#increase j
j += 1
print(ar)
#############################################################################################################################
# Adding parser
#############################################################################################################################
parser = argparse.ArgumentParser(description='MERGE algorithm from ch 2')
parser.add_argument('-a', '--array', type=str, metavar='', required=True, help='One List of integers composed of 2 sorted halves. Sorting must start from smallest to largest for each of the halves.')
args = parser.parse_args()
args_list_st=args.array.split(',') # list of strings
args_list_int=[]
for i in args_list_st:
args_list_int.append(int(i))
if __name__ == "__main__":
merge(args_list_int)
The problem:
When I try to sort the array as shown in the book the merged array that is returned contains two 6es and the 7 is lost.
$ ./2.merge.py -a=2,4,5,7,1,2,3,6
[2, 4, 5, 7, 1, 2, 3, 6]
p 0 q 3 r 7
n1 is: 4
n2 is: 4
[0, 0, 0, 0, 0] 5
[0, 0, 0, 0, 0] 5
[2, 4, 5, 7, inf]
[1, 2, 3, 6, inf]
p 0
r 7
[1, 2, 2, 3, 4, 5, 6, 6]
This does how ever not happen with arrays of any number higher than 6.
$ ./2.merge.py -a=2,4,5,7,1,2,3,8
[2, 4, 5, 7, 1, 2, 3, 8]
p 0 q 3 r 7
n1 is: 4
n2 is: 4
[0, 0, 0, 0, 0] 5
[0, 0, 0, 0, 0] 5
[2, 4, 5, 7, inf]
[1, 2, 3, 8, inf]
p 0
r 7
[1, 2, 2, 3, 4, 5, 7, 8]
I showed it to a colleague in my class without success. And I've walked it through manually with numbers on paper snippets but withouth success. I hope someone can find my silly mistake because I'm completely stuck.
Thanks
As r is the index of the last value in arr, you need to add one to it to make a range that also includes that final index:
for k in range(p, r + 1):
# ^^^^^
Note that your code could be greatly reduced if you would use list slicing.
Brother you made a very small mistake in this line
for k in range(p,r):
Here you loop is running from p to r-1 and your last index i.e r, will not get iterated.
So you have to use
for k in range(p,r+1):
And in the second testcase a=[2,4,5,7,1,2,3,8]
You are getting the correct output even with your wrong code because you are overwriting the values in array ar and your current code was able to sort the array till index r-1 and the number present at index r will be the same which was present before the execution of your merge function i.e 8
Try using this testcase: [2, 4, 5, 8, 1, 2, 3, 7]
And your output will be [1, 2, 2, 3, 4, 5, 7, 7]
Hope this helped
I'm trying to find the column wise combinations for given m x n 2d matrix. For example if the matrix is 3 x 3, it might be,
1 2 3
4 5 6
7 8 9
And I want the combinations, 3 at time, like -
1, 4, 7
1, 4, 8
1, 4, 9
1, 5, 7
.
.
1, 6, 7
I've tried the following recursive procedure in Python 3:
def getKeys(keychars):
temp = []
create(keychars, 0, 0, temp)
def create(kc, i, j, temp):
if i == 3:
print(temp)
del temp[-1]
return
temp.append(kc[i][j])
for j in range(3):
create(kc, i+1, j, temp)
def main():
keychars = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
getKeys(keychars)
main()
(If running the snippet gives you an error, please try in an IDE.)
But the problem is that, I'm not sure how or when to clear the temp variable. The outputs are like - 1,4,7 1,4,7,8 1,4,7,8,9 1,4,7,8,9,5
That is the temp variable retains the previous results. Any help would be appreciated.
List:
x = [1, 6, 2, 7, 1, 6, 1]
len(x)
> 7
How would I split the list for the first 3 and last 3, thus value 7 is left alone using list slicing methods?
Output
x[0:2,4:6] #<-- This doesn't work
> [1, 6, 2, 1, 6, 1] #<-- Expected output
Meeting OP requeriment: "Is there a way to just keep it same brackets? x[...,...] similar to this one? " (not just using x[:3]+x[-3:]):
Use numpy.delete together with numpy.r_. Specify which first number of elements n1 and which last number of elements n2 you want to keep this way
import numpy as np
x = [1, 6, 2, 7, 1, 6, 1]
n1 = 3 # Keep first n1 elements
n2 = 3 # Keep last n2 elements
print(list(np.delete(x,(np.r_[n1:len(x)-n2])))) # [1 6 2 1 6 1]
You could do: x[0:3]+x[4:7] or x[:3]+x[-3:]. The second one gets the first 3 elements from the last and the first three elements from the right.