python 3 vector subtraction with out numpy - python-3.x

I'm fairly new to coding in the python3 language. I'm trying to construct a function that takes two vectors and subtracts them. Any help would be great. Thank you in advance.
Write a function vecSubtract(vector01, vector02) which takes in two vectors as arguments, and returns the vector which is equal to vector01-vector02.
def vecSubtract(vector01,vector02):
for i in range(min(len(vector01), len(vector02))):
result = [vector01[i]-vector02[i] ]
return result
vector01 = [3, 3, 3]
vector02 = [4, 4, 4]
print(vecSubtract(vector01,vector02))

While you are looping over the vectors (lists actually), you are overwriting your result variable every time.
You probably want to use a list comprehension instead.
def vecSubtract(vector01, vector02):
result = [vector01[i] - vector02[i] for i in range(min(len(vector01), len(vector02)))]
return result
vector01 = [3, 3, 3]
vector02 = [4, 4, 4]
print(vecSubtract(vector01,vector02))
If you really want to use a for loop, you should use result.append() instead of overwriting the variable every time.
Also, it is probably not right to allow subtraction of vectors of different lengths by ignoring the surplus elements in the longer vector. Instead you should probably test that the two vectors are the same length and have the script throw an error if they are not.

Related

Single slice getting elements from beginning and end of list in Python?

The first and last N elements of a list in Python can be gotten using:
N = 2
my_list = [0, 1, 2, 3, 4, 5]
print(my_list[:N] + my_list[-N:])
# [0, 1, 4, 5]
Is it possible to do this with a single slice in pure Python? I tried my_list[-N:N], which is empty, and my_list[N:-N], which gives exactly the elements I don't want.
For the builtin types, slices are by definition consecutive – a slice represents a start, end and step between them. There is no way for a single slice operation to represent non-consecutive elements, such as head and tail of a list.

Recursion for generating subsets of a list

I would like to know for this function, why does after it runs and returns [[],[1]] which is the last line of the function? Then it would run the line smaller = genSubset(L[:-1]) again and again. I visualized the code from pythontutor. However, i do not understand why it works this way. Someone please enlighten me. Thank You.
This function generates all the possible subsets of a given list, so, for example, input list is [1,2,3]. It would return [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]].
def genSubsets(L):
res = []
if len(L) == 0:
return [[]] #list of empty list
smaller = genSubsets(L[:-1]) # all subsets without last element
extra = L[-1:] # create a list of just last element
new = []
for small in smaller:
new.append(small+extra) # for all smaller solutions, add one with last element
return smaller+new # combine those with last element and those without
print(genSubsets([1,2,3]))
This function is recursive, that means - it calls itself. when it finishes one recursion iteration - it returns to where it stopped. This is exactly at the line smaller = getSubsets(L[:-1]) but notice that it wont run it again, but instead continue until it finishes the call. This recursion happens n times (where n is the list's length), and you will see this behavior exactly n times before the function finally returns the subsets.
I hope i understood correctly the question and managed to answer it :)

Assigning values to discontinued slices in a ndarray

I have a base array that contains data. Some indices in that array need to be re-assigned a new value, and the indices which do are discontinued. I'd like to avoid for-looping over all of that and using the slice notation as it's likely to be faster.
For instance:
arr = np.zeros(100)
sl_obj_1 = slice(2,5)
arr[sl_obj_1] = 42
Works for a single slice. But I have another discontinued slice to apply to that same array, say
sl_obj_2 = slice(12,29)
arr[sl_obj_1] = 55
I would like to accomplish something along the lines of:
arr[sl_obj_1, sl_obj_2] = 42, 55
Any ideas?
EDIT: changed example to emphasis that sequences are or varying lenghts.
There isn't a good way to directly extract multiple slices from a NumPy array, much less different-sized slices. But you can cheat by converting your slices into indices, and using an index array.
In the case of 1-dimensional arrays, this is relatively simple using index arrays.
import numpy as np
def slice_indices(some_list, some_slice):
"""Convert a slice into indices of a list"""
return np.arange(len(some_list))[some_slice]
# For a non-NumPy solution, use this:
# return range(*some_slice.indices(len(some_list)))
arr = np.arange(10)
# We'll make [1, 2, 3] and [8, 7] negative.
slice1, new1 = np.s_[1:4], [-1, -2, -3]
slice2, new2 = np.s_[8:6:-1], [-8, -7]
# (Here, np.s_ is just a nicer notation for slices.[1])
# Get indices to replace
idx1 = slice_indices(arr, slice1)
idx2 = slice_indices(arr, slice2)
# Use index arrays to assign to all of the indices
arr[[*idx1, *idx2]] = *new1, *new2
# That line expands to this:
arr[[1, 2, 3, 8, 7]] = -1, -2, -3, -8, -7
Note that this doesn't entirely avoid Python iteration—the star operators still create iterators and the index array is a regular python list. In a case with large amounts of data, this could be noticeably slower than the manual approach, because it calculates each index that will be assigned.
You will also need to make sure the replacement data is already the right shape, or you can use NumPy's manual broadcasting functions (e.g. np.broadcast_to) to fix the shapes. This introduces additional overhead—if you were rely on automatic broadcasting, you're probably better off doing the assignments in a loop.
arr = np.zeros(100)
idx1 = slice_indices(arr, slice(2, 5))
idx2 = slice_indices(arr, slice(12, 29))
new1 = np.broadcast_to(42, len(idx1))
new2 = np.broadcast_to(55, len(idx2))
arr[*idx1, *idx2] = *new1, *new2
To generalize to more dimensions, slice_indices will need to take care of shape, and you'll have to be more careful about joining multiple sets of indices (rather than arr[[i1, i2, i3]], you'll need arr[[i1, i2, i3], [j1, j2, j3]], which can't be concatenated directly).
In practice, if you need to do this a lot, you'd probably be better off using a simple function to encapsulate the loop you're trying to avoid.
def set_slices(arr, *indices_and_values):
"""Set multiple locations in an array to their corresponding values.
indices_and_values should be a list of index-value pairs.
"""
for idx, val in indices_and_values:
arr[idx] = val
# Your example:
arr = np.zeros(100)
set_slices(arr, (np.s_[2:5], 42), (np.s_[12:29], 55))
(If your only goal is making it look like you are using multiple indices simultaneously, here are two functions that try to do everything for you, including broadcasting and handling multidimensional arrays.)
1 np.s_

Godot - How do I create a subarray of a list in Gdscript?

I know it's possible to slice an array in python by array[2:4]. The way I get around this is to just loop through the indexes I want and append them to the new_list. This way requires more work is there just a simple way to do it like in python?
You can use the Array.slice() method added in Godot 3.2 for this purpose:
Array slice ( int begin, int end, int step=1, bool deep=False )
Duplicates the subset described in the function and returns it in an array, deeply copying the array if deep is true. Lower and upper index are inclusive, with the step describing the change between indices while slicing.
Example:
var array = [2, 4, 6, 8]
var subset = array.slice(1, 2)
print(subset) # Should print [4, 6]

Is there a way to sort an unsorted list with some repeated elements?

I am trying to sort an unsorted list [4, 5, 9, 9, 0, 1, 8]
The list has two repeated elements. I have tried to approach the question by having a loop that goes through each element comparing each element with the next in the list and then placing the smaller element at the start of the list.
def sort(ls:
ls[x]
x = [4, 5, 9, 9, 0, 1, 8]
while len(x) > 0:
for i in the range(0, len(x)):
lowest = x[i]
ls.append(lowest)
Please, could someone explain where I am going wrong and how the code should work?
It may be that I have incorrectly thought about the problem and my reasoning for how the code should work is not right
I do not know, if this is exactly what you are looking for but try: sorted(ListObject).
sorted() returns the elements of the list from the smallest to the biggest. If one element is repeated, the repeated element is right after the original element. Hope that helped.
Yes, you can try x.sort() or sorted(x). Check this out https://www.programiz.com/python-programming/methods/built-in/sorted. Also, in your program I don't see you making any comparisons, for example, if x[i] <= x[i+1] then ...
This block of code is just gonna append all the elements in the same order, till n*n times.
Also check this https://en.wikipedia.org/wiki/Insertion_sort
For a built-in Python function to sort, let y be your original list, you can use either sorted(y) or y.sort().Keep in mind that sorted(y) will return a new list so you would need to assign it to a variable such as x=sorted(y); whereas if you use x.sort() it will mutate the original list in-place, so you would just call it as is.
If you're looking to actually implement a sorting function, you can try Merge Sort or Quick Sort which run in O (n log n) in which will handle elements with the same value. You can check this out if you want -> https://www.geeksforgeeks.org/python-program-for-merge-sort/ . For an easier to understand sorting algorithm, Insertion or Bubble sort also handle duplicate as well but have a longer runtime O (n^2) -> https://www.geeksforgeeks.org/python-program-for-bubble-sort/ .
But yea, I agree with Nameet, what you've currently posted looks like it would just append in the same order.
Try one of the above suggestions and hopefully this helps point you in the right direction to if you're looking for a built-in function or to implement a sort, which can be done in multiple ways with different adv and disadv to each one. Hope this helps and good luck!
There are several popular ways for sorting. take bubble sort as an example,
def bubbleSort(array):
x = len(array)
while(x > 1): # the code below make sense only there are at least 2 elements in the list
for i in range(x-1): # maximum of i is x-2, the last element in arr is arr[x-1]
if array[i] > array[i+1]:
array[i], array[i+1] = array[i+1], array[i]
x -= 1
return array
x = [4, 5, 9, 9, 0, 1, 8]
bubbleSort(x)
your code has the same logic as below
def sorts(x):
ls = []
while len(x) > 0:
lowest = min(x)
ls.append(lowest)
x.remove(lowest)
return ls
x = [4, 5, 9, 9, 0, 1, 8]
sorts(x)
#output is [0, 1, 4, 5, 8, 9, 9]

Resources