I'm a new programmer and I don't understand:
np.array([range(i, i+3) for i in [2,4,6]])
I know that in the range function there is a start, stop and step, but it's written quite differently here.
The output is a 3*3 array
234
456
678
I don't understand how this array came about. What does the I+3 mean? Are the 2,4,6 x values? What exactly if the for loop doing in this case? What is it iterating over?
Thanks for the help.
If I break down that line of code a little bit I can show you what happens.
The following line is a list comprehension, it's saying return I where I is set to each number in the list [2,4,6]. This returns a list that looks like [2,4,6]. So that's essentially useless because you're not manipulating your original list.
[I for I in [2,4,6]]
when you put this inside np.array() it just creates an array from your list.
Now with the following code, your going through each number in the range 2-5 not including 5 (5 is I+3)
for i in range(2,5):
print(i)
2
3
4
You could also do
for i in range(2,5):
print(np.array([range(2,4)]))
[[2 3]]
[[2 3]]
[[2 3]]
Which is a loop that executes 3 times, and prints an array which contains a range from 2-4 in it.
When you combine everything in
[range(I, I+3) for I in [2,4,6]]
You're saying for each number in the list [2,4,6] return a range from that number up to that number + 3 and put that in a list, which returns
[range(2, 5), range(4, 7), range(6, 9)]
Then you convert that to an array to get
array([[2, 3, 4],
[4, 5, 6],
[6, 7, 8]])
np.array( # This is a numpy library's 2D data structure array.
[
range(i, i+3) # range function which produces iterator from i to i+2 (exclusive of end) i.e. if i = 1, range(1, 4) will give [1, 2, 3]
for i in [2,4,6] # Basic list comprehension for loop
]
)
Related
I newbie in python and I have a trouble how can I make my loop with that shape below and getting the total number of each line, I tried the code below but it seems it doesn't right
I should use list in loop like the declaration below, I appreciate who can help me.
data = [1, 2, 3, 4, 5]
Expected output:
[1, 2, 3, 4, 5, 15]
[2, 3, 4, 5, 14]
[3, 4, 5, 12]
[4, 5, 9]
[5, 5]
This is what I tried but it doesn't use list ,I think it's wrong
data = 5
for i in range(data):
for j in range(i+1):
print("[",j+1, end=" "+" ]")
print("[ ]")
Usually in these kind of exercises you shouldn't build the string yourself(talking about brackets). Those brackets are part of the representation of the lists in Python. So build your list object and the final result is gonna be printed as you expected. So don't attempt to put individual numbers, spaces, brackets together yourself.
You can use:
data = [1, 2, 3, 4, 5]
for i in range(len(data)):
slice_ = data[i:]
print(slice_ + [sum(slice_)])
Explanation:
Basically in every iteration, you create a slice of the list by specifying the start point to the end. Start point comes from the range(len(data)) range object.
first iteration : From index 0 to end.
second iteration: From index 1 to end.
...
Then you concatenate the slice with the sum of the slice. But you have to put the sum inside a list because a list can't be concatenated with an int. Of course other option is to .append() it before printing:
for i in range(len(data)):
slice_ = data[i:]
slice_.append(sum(slice_))
print(slice_)
I have a Python code below that will zip through two arrays and print the output. What would the equivalent of this code be in MATLAB?
x = [1, 2, 3, 4, 5]
y = [1, 2, 3, 4, 5]
for i, j in zip(x, y):
print(i, j)
There are two things you can do.
The most natural method in MATLAB is iterating over the index:
x = [1, 2, 3, 4, 5];
y = [10, 20, 30, 40, 50];
for i = 1:numel(x)
disp([x(i), y(i)]);
end
The alternative is to concatenate the two arrays. MATLAB's for loop iterates over the columns of the array:
for i = [x;y]
disp(i.');
end
Note that this alternative is typically much less efficient, because concatenation requires copying all the data.
You can iterate through the index, matlab likes for loop.
matlab
for i=1:5
x(i), y(i)
end
For MATLAB, there is no equivalent for the python zip function; if you were looking for something like that, I would recommend checking out this SO answer about creating a zip function in MATLAB.
Otherwise, iterating through indices works.
% Create lists
x = [1 2 3 4 5];
y = [1 2 3 4 5];
% Assuming lists are same length, iterate through indices
for i = 1:length(x)
disp([x(i) y(i)]);
end
I have a piece of C code that can only handle an array of size 20. The array that my instrument outputs is much smaller than what the function requires. Is there a numpy or math function that can "scale up" an array to any specific size while maintaining its structural integrity? For example:
I have a 8 element array that is basically a two ramp "sawtooth" meaning its values are :
[1 2 3 4 1 2 3 4]
What I need for the C code is a 20 element array. So I can scale it, by padding linear intervals of the original array with "0"s , like:
[1,0,0,2,0,0,3,0,0,4,0,0,1,0,0,2,0,0,3,0]
so it adds up to 20 elements. I would think this process is the opposite of "decimation". (I apologize ,I'm simplifying this process so it will be a bit more understandable)
Based on your example, I guess the following approach could be tweaked to do what you want:
upsample with 0s: upsampled_l = [[i, 0, 0] for i in l] with l being your initial list
Flatten the array flat_l = flatten(upsampled_l) using a method from
How to make a flat list out of a list of lists? for instance
Get the expected length final_l = flat_l[:20]
For instance, the following code gives the output you gave in your example:
l = [1, 2, 3, 4, 1, 2, 3, 4]
upsampled_l = [[i, 0, 0] for i in l]
flat_l = [item for sublist in upsampled_l for item in sublist]
final_l = flat_l[:20]
However, the final element of the initial list (the second 4) is missing from the final list. Perhaps it's worth upsampling with only one 0 in between ([i, 0] instead of [i, 0, 0]) and finally do final_l.extend([0 for _ in range(20 - len(final_l))]).
Hope this helps!
You can manage it in a one-liner by adding zeros as another axis, then flattening:
sm = np.array([1, 2, 3, 4, 1, 2, 3, 4])
np.concatenate([np.reshape(sm, (8, 1)), np.zeros((8, 3))], axis=1).flatten()
Specifications:
I want to use the remove function (in lists) and I'd prefer to avoid typecasting.
l = [2, 3, 3, 4, 6, 4, 6, 5]
q=len(l)
for i in range (0, q):
for g in range (i+1, q):
if l[g]==l[i]:
q-=1 #decremented q to account for reduction in list size.
l.remove(l[g])
print(l)
Error: if l[g]==l[i]:
IndexError: list index out of range
I know that similar questions have been asked by users previously. As the aforementioned constraints were absent in them, I would like to request you to treat this as a separate question. Thanks!
>>> l = [2, 3, 3, 4, 6, 4, 6, 5]
>>> s = set(l)
>>> t = sorted(s)
>>> print(t)
[2, 3, 4, 5, 6]
Using set is a simple and straight-forward way to filter your collection. If you don't need the list in a specific order, you can just use the set from thereon. The sorted function returns a list (using the default ordering).
Since you mentioned you don't want typecasting, so my solution is using while loop
l = [2, 3, 3, 4, 6, 4, 6, 5]
q=len(l)
i = 0
while i<len(l):
g = i+1
while (g < q):
if l[g]==l[i]:
q-=1 #decremented q to account for reduction in list size.
l.remove(l[g])
g += 1
i += 1
print(l)
Now, allow me to explain what was the problem in your code. When you use range function, it holds the starting and the ending value at the first run of the loop, so even if you change the limits afterwards in the loop, still, it won't change the range loop so eventually, you get index out of bounds error.
Hope this helps you :)
Your solution does not work, because range() store the value of q, and will ignore the change of q's value later. Eg:
>>> m = 10
>>> for i in range(m):
... m=0
... print(i)
...
0
1
2
3
4
5
6
7
8
9
Even if I change m, range() will still go 10 times in the loop. So, when you change the size of the list, even if you change q, you will still try to reach elements that does not exist anymore.
I am working through some code trying to understand some Python mechanics, which I just do not get. I guess it is pretty simple and I also now, what it does, but i do not know how it works. I understand the normal use of for-loops but this here... I do not know.
Remark: I know some Python, but I am not an expert.
np.array([[[S[i,j]] for i in range(order+1)] for j in range(order+1)])
The second piece of code, I have problems with is this one:
for i in range(len(u)):
for j in range(len(v)):
tmp+=[rm[i,j][k]*someFuction(name,u[i],v[j])[k] for k in range(len(rm[i,j])) if rm[i,j][k]]
How does the innermost for-loop work? And also what does the if do here?
Thank you for your help.
EDIT: Sorry that the code is so unreadable, I just try to understand it myself. S, rm are numpy matrices, someFunction returns an array with scalar entries, andtmp is just a help variable
There are quite a few different concepts inside your code. Let's start with the most basic ones. Python lists and numpy arrays have different methodologies for indexation. Also you can build a numpy array by providing it a list:
S_list = [[1,2,3], [4,5,6], [7,8,9]]
S_array = np.array(S_list)
print(S_list)
print(S_array)
print(S_list[0][2]) # indexing element 2 from list 0
print(S_array[0,2]) # indexing element at position 0,2 of 2-dimensional array
This results in:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[[1 2 3]
[4 5 6]
[7 8 9]]
3
3
So for your first line of code:
np.array([[[S[i,j]] for i in range(order+1)] for j in range(order+1)])
You are building a numpy array by providing it a list. This list is being built with the concept of list comprehension. So the code inside the np.array(...) method:
[[[S[i,j]] for i in range(order+1)] for j in range(order+1)]
... is equivalent to:
order = 2
full_list = []
for j in range(order+1):
local_list = []
for i in range(order+1):
local_list.append(S_array[i, j])
full_list.append(local_list)
print(full_list)
This results in:
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
As for your second snippet its important to notice that although typically numpy arrays have very specific and constant (for all the array) cell types you can actually give the data type object to a numpy array. So creating a 2-dimensional array of lists is possible. It is also possible to create a 3-dimensional array. Both are compatible with the indexation rm[i,j][k]. You can check this in the following example:
rm = np.array(["A", 3, [1,2,3]], dtype="object")
print(rm, rm[2][0]) # Acessing element 0 of list at position 2 of the array
rm2 = np.zeros((3, 3, 3))
print(rm2[0, 1][2]) # This is also valid
The following code:
[rm[i,j][k]*someFuction(name,u[i],v[j])[k] for k in range(len(rm[i,j])) if rm[i,j][k]]
... could be written as such:
some_list = []
for k in range(len(rm[i,j])):
if rm[i, j][k]: # Expecting a boolean value (or comparable)
a_list = rm[i,j][k]*someFuction(name,u[i],v[j])
some_list.append(a_list[k])
The final detail is the tmp+=some_list. When you sum two list they'll be concatenated as can been seen in this simple example:
tmp = []
tmp += [1, 2, 3]
print(tmp)
tmp += [4, 5, 6]
print(tmp)
Which results in this:
[1, 2, 3]
[1, 2, 3, 4, 5, 6]
Also notice that multiplying a list by a number will effectively be the same as summing the list several times. So 2*[1,2] will result in [1,2,1,2].
Its a list comprehension, albeit a pretty unreadable one. That was someome doing something very 'pythonic' in spite of readablity. Just look up list comprehensions and try to rewrite it yourself as a traditional for loop. list comprehensions are very useful, not sure I would have gone that route here.
The syntax for a list comprehension is
[var for var in iterable if optional condition]
So this bottom line can be rewritten like so:
for k in range(len(rm[i,j]):
if rm[i,j][k]:
tmp+= rm[i,j][k]*someFunction(name,u[i],v[j])[k]