I have a 2D matrix called A0
A0 = [[0 for x in range(3)] for y in range(3)]
I have a function called newProb which takes this as an argument and returns another 2D matrix in the following way:-
A1 = newProb(A0)
So, I want to put this code into a loop.
A1 = newProb(A0)
A2 = newProb(A1)
A3 = newProb(A2)
A4 = newProb(A3)
Any help will be appreciated. Thanks!
P.S. I have to make 100 calls to that function in the above way
Rather than trying to create local variables in your loop, you'd be better off storing the results in a list. Your list's index will line up nicely with your naming convention.
A = []
A.append([[0 for x in range(3)] for y in range(3)])
A[1] = newProb(A[0])
A[2] = newProb(A[1])
# ...
You can then easily put this into a loop with a range.
# start the range off by 1
for i in range(1, 10):
A[i] = newProb(A[i - 1])
This could also be written as
for i in range(10):
A.append(newProb(A[i]))
Use a dict:
A = {}
A[0] = [[0 for x in range(3)] for y in range(3)]
for i in range(1, 101):
A[i] = newProb(A[i-1])
You can store your values in a list generated like so:
A = [A0]
for i in range(99):
A.append(newProb(A[i]))
Combining the answers from #jez and #Soviut:
A = []
A.append([[0 for x in range(3)] for y in range(3)])
for i in range(100):
A.append(newProb(A[-1])
A[-1] is the last element in the list.
If you just need the 'final' value, after the 100st loop:
value = [[0 for x in range(3)] for y in range(3)]
for i in range(100):
value = newProb(value)
Round out the answers with a while loop
A = [A0]
while len(A) < 100:
A.append(newProb(A[-1]))
Related
I have a randomly generated list of items, and I want to replace every second and third item in that list with the number 0. For the replacement of every second item I have used the code below.
import random
x = [random.randint(0,11) for x in range(1000)]
y = [random.randint(0,11) for x in range(1000)]
a = (x + y)
a[::2] = [0]*(2000//2)
print(a)
It works fine, but I can't use the same method with replacing every third item since it gives me an error
attempt to assign sequence of size 666 to extended slice of size 667
I thought of using list comprehension, but I'm unsure of how to execute it, and I could not find a definite answer in my research.
In the case of every second element, the size of [0]*(2000//2) is equal to the size of a[::2], which is 1000. That is why you are not getting an error. But in the case of a[::3], there are 667 elements and [0]*(2000//3) returns a list of size 666, which is not possible to assign. You can use math.ceil to solve this issue. As:
import random
from math import ceil
x = [random.randint(0, 11) for x in range(1000)]
y = [random.randint(0, 11) for x in range(1000)]
a = (x + y)
index = 2
a[::index] = [0] * ceil(2000/index)
print(a)
You can simply replace 2000//2 with len(a[::2]) like this
import random
x = [random.randint(0,11) for x in range(1000)]
y = [random.randint(0,11) for x in range(1000)]
a = (x + y)
a[::2] = [0]*len(a[::2])
print(a)
b = (x + y)
b[::3] = [0]*len(b[::3])
print(b)
Something like this, where every other or every 3rd become zero.
[0 if (i+1)%2==0 or (i+1)%3==0 else x for i, x in enumerate(a)]
Not quite as neat as subscripting the list outright, but this can be done with the % operator and indices:
import random
x = [random.randint(0,11) for x in range(1000)]
y = [random.randint(0,11) for x in range(1000)]
a = (x + y)
for i, v in enumerate(a):
if (i+1) % 2 == 0 or (i+1) % 3 == 0:
a[i] = 0
# if you prefer a comprehension:
a = [0 if (i+1) % 3 == 0 or (i+1) % 2 == 0 else v for i, v in enumerate(a)]
print(a)
[3, 6, 0, 5, 1, 0, 8, 5, 0, 1, 5, 0, 2, 3, 0, 7, 9, 0, ... ]
Others have explained how replacement is done, but the same result could be achieved by not generating these random throwaway numbers in the first place.
from random import randint
N = 2_000
[randint(0, 11) if (x % 2) * (x % 3) != 0 else 0
for x in range(1, N + 1)]
To get this done efficiently I would recommend using the numpy module here is the code
import numpy as np
a = np.random.randint(0,12,(2000,))
a[::2] = 0
a[::3] = 0
a = a.tolist()
print(a)
np.random.randint takes in 3 arguments. the first is the lower bound inclusive, the second is the upper bound exclusive and the third is a tuple of the array dimensions. In this case a 1-d array of 2000. using numpy you can just use slicing to set the parts you want to zero and then use tolist() to convert back to a list if you need to or keep it as a numpy array.
I'm trying to create a function in python (without numpy) that would imitate matrix multiplication in numpy. The program contains 2 functions. First function takes in 2 lists (l1 and l2) as input and creates a dummy list (dummy). The second function does the matrix multiplication of the lists l1 and l2 and inputs the values in the dummy list (dummy). The issue is that in the final output, the column values are being added and repeated in each row. However, if I hard code the dummy list in the program, it is giving correct output. If I run the first function to create dummy list separately, I'm getting correct output. Not sure where I'm going wrong. Providing both the codes below. Please help.
#Following code is giving me erroneous result:
l1 = [[1,2],[3,4],[5,6]]
l2 = [[7,8,0],[9,10,5]]
def dummy_matrix(l1,l2):
g = len(l1)
h = len(l2[0])
m = []
p = []
for j in range(h):
p.append(0)
for i in range(g):
m.append(p)
dummy = m
return(dummy)
def mat_mul(l1,l2):
f = dummy_matrix(l1,l2)
for a in range(len(l1)):
for b in range(len(l2[0])):
for c in range(len(l2)):
f[a][b] += l1[a][c]*l2[c][b]
return(f)
mat_mul(l1,l2)
#Following code has hard coded dummy list and is giving correct output
l1 = [[1,2],[3,4],[5,6]]
l2 = [[7,8,0],[9,10,5]]
def dummy_matrix(l1,l2):
g = len(l1)
h = len(l2[0])
m = []
p = []
for j in range(h):
p.append(0)
for i in range(g):
m.append(p)
dummy = m
return(dummy)
def matrix_multi(l1,l2):
f = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
for a in range(len(l1)):
for b in range(len(l2[0])):
for c in range(len(l2)):
f[a][b] += l1[a][c]*l2[c][b]
return(f)
matrix_multi(l1,l2)
You create your dummy_matrix wrong. You first create a row called p, append some zeros to it and then you append the same row multiple times.
dm = dummy_matrix(l1, l2)
dm[1][2] = 1
print(dm)
You can notice that this will modify multiple rows, showing that they are in fact the same reference.
You need to create fresh list for each row:
m = []
for i in range(g):
p = []
for j in range(h):
p.append(0)
m.append(p)
So, I know that is super simple, but I don't have idea how to found the answer in google :<
It would be grate if you could tell me how I can optimalize this, or just let me know how this type of list is called.
The function takes one argument "n" and return list of numbers from 1 to "n" and every number appends "n" times
def my_function(n):
x = []
y = 1
for i in range(n):
for j in range(n):
x.append(y)
y += 1
return x
my_function(3)
Should return : [1,1,1,2,2,2,3,3,3]
Here's one simple way with no extra libraries involved:
def my_function(n):
# returns array from 1 to n+1 (e.g. if n=3, x=[1,2,3])
x = list(range(1, n+1))
# create a new array with every element of x repeated n times
# Returns x = [1,2,3,1,2,3,1,2,3]
x = x * n
# Sort all elements of x to group them
# Returns x = [1,1,1,2,2,2,3,3,3]
x.sort()
return x
my_function(3)
With no comments/combined, it would just be:
def my_function(n):
x = list(range(1, n+1))* n
x.sort()
return x
You mean smaller like this?
def foo(n):
result = []
for i in range(1, n + 1):
result += ([i]*n)
return result
foo(3)
One liner pythonic way:
def foo(n):
return [i for i in range(1, n+1) for _ in range(n)]
foo(3)
While I was creating a basic for-loop in Python within a function in order to work with a dynamic variable length (z) I've just come across the following error:
Rs = []
z = []
N = 120
m = 1
for i in range(1, N):
Rs[i] = z[m]
m = m + 1
Rs[i] = z[m]
IndexError: list index out of range
For the sake of clarity, I will explain better what I'm trying to do.
I would like to solve an equation system which is composed by a dynamical number of unknowns.
I've started to use the "static" method and It works perfectly. Basically, the code is more or less as follows:
from scipy.optimize import fsolve
def fixEqSyst(z):
v1 = z[0]
v2 = z[1]
v3 = z[2]
v4 = z[3]
f=np.zeros(4)
f[0] = 2*v1-3*v2+7*v3**2
f[1] = v1+3*v2**2-9*v3
f[2] = -3v1**2+12*v2+7*v3
f[3] = 4*v1+5*V2*v3
return f
z = fsolve(fixEqSyst, [0, 0, 0, 0])
Basing on the fact that now I will face with a dynamic number of unknowns and functions, is there any alternative solution than of what I've already put in place? (with a for-loop strategy)
Just in the first iteration of your loop you get
Rs[1] = z[1]
but z[1] don't exists, because z = [].
(The same for Rs[1].)
I haven't any idea how to fix it because I'm unable to guess what you wanted perform with you code.
Maybe you wanted to copy the contain of your - supposed nonempty - list z to Rs. Then they are 2 different simple solutions:
Rs = z
Attention! This is not a copy operation, this only associates other name to the same object, so every change in z will produce the same change in Rs and vice versa.
Rs = z[:]
This is the true (but shallow) copy. For simple lists this is the same as a deep copy.
When you assign a value to an array in python, the element must already exist. When you are assigning Rs[i] = z[m], you are assigning values out of the range of the list. You can use the += operator on a list in order to make it large enough, like this:
Rs = []
z = []
N = 120
m = 1
for i in range(m+N):
z += [m+i]
for i in range(N):
Rs += [z[m]]
m = m + 1
Note that += can only concatenate a list to another list. So this will work:
mylist = [1, 2, 3]
mylist += [4]
But this will not:
mylist = [1, 2, 3]
mylist += 4
Here is more on the += operator on lists.
Why does this code doesn't transpose the list of list
import sys
t = input()
for k in range(t):
n,m = [int(i) for i in raw_input().strip().split()]
A = [[None]*m]*n
B = [[None]*n]*m
for l in range(n):
A[l] = raw_input().strip().split()
for j in range(m):
for i in range(n):
B[j][i] = A[i][j]
print B
I know there are better methods to transpose a matrix but why does this doesn't work?
Replace
A = [[None]*m]*n
B = [[None]*n]*m
with
A = [[None for x in range(m)] for x in range(n)]
B = [[None for x in range(n)] for x in range(m)]
Why?
>>> l = [2]*5
>>> l
[2,2,2,2,2]
>>> [id(value) for value in l]
[26089400, 26089400, 26089400, 26089400, 26089400]
Can you see what happened there?
There's just one copy in memory holding a value '2'. All list elements are pointing to that same memory location holding the value '2'.
So, when you do:
A = [[None]*m]*n
you are creating a 2d array with elements pointing to the same memory location. Changing one of them, changes the value stored at that common memory location, hence changes value stored by all the elements!
That is why the program didn't work.
Read more about how all this works in Python, in detail, here:
http://foobarnbaz.com/2012/07/08/understanding-python-variables/