Making All Elements Of An Array The Same - python

I am trying to choose the larger of the first and last elements of an array of len(3) and make that all the elements of the array:
def max_end3(nums):
a = max(nums[0], nums[2])
for i in nums:
i = a
return nums

So you want to return a new list that is the maximum of the first and last element?
In Python you can access the last element with [-1].
so a solution that doesn't care about the length of the list(minimum one element to work) would look like this:
def set_list_to_max_of_first_last(nums):
return [max(nums[0], nums[-1])] * len(nums)
What we do here is we use [] to create a new list with one element. Then we make the array as long as the original with identical entries.
HTH

Rather than iterating the list -
def max_end3(nums):
max_elem = max(nums[0], nums[-1])
n = len(nums)
return [max_elem] * n
>>> l = [1,5,67,100]
>>> max_end3(l)
[100, 100, 100, 100]

Related

How to find position where a list is sorted up to using loops?

For example, [4,5,6,1,2,3] should return 2 since the list is sorted up to the 2nd position.
If the list is sorted every value will always be greater or equal to the one the precedes it, so you don't need loops; a single loop will work. So you can zip() the list with itself to compare adjacent values. Use enumerate() to get the index and catch the exception when the list is actually sorted:
l = [4,5,6,1,2,3]
try:
print(next(i for i, (a,b) in enumerate(zip(l, l[1:])) if a > b))
except StopIteration:
print("list is sorted")
# prints 2
You can alternatively pass a default to next() instead of the try/catch. So if your list is already sorted and you want -1 in that case:
l = [1, 2, 3, 4, 5]
next((i for i, (a,b) in enumerate(zip(l, l[1:])) if a > b), -1)
# -1
If list is sorted if the following entry is bigger than the current entry. Thus you can look at the differences between following entries to find the argument of the last-ordered index in the array. First, make two lists as follows:
l = [4,5,6,1,2,3]
temp1 = l[1:]
temp2 = l[0:-1]
Then we can compute the difference in a 1-line for loop:
diff = [temp1[ii] - temp2[ii] for ii in range(len(temp1))] # [1, 1, -5, 1, 1]
Now we need to find the first number in diff which is smaller than 0.
try:
solution = [diff[ii] < 0 for ii in range(len(diff))].index(True)
except ValueError:
solution = len(l)
Where the try and except is set to catch a case where the array is sorted entirely
I think an easier to digest implementation would be like this:
Enumerate the list, and at every index, check if the next number is smaller, and return the index if so. Since we can't check the next index when the current index is at the end, stop at the second last element.
l = [4,5,6,1,2,3]
l2 = [4,5,6,7,8,3]
def get_unsorted_index(input_list):
for index, value in enumerate(input_list[:-1]):
if input_list[index+1] < value:
return index
return len(input_list)-1
print(get_unsorted_index(l))
print(get_unsorted_index(l2))
Output:

Find missing elements in a list created from a sequence of consecutive integers with duplicates in O(n)

This is a Find All Numbers Disappeared in an Array problem from LeetCode:
Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array),
some elements appear twice and others appear once.
Find all the elements of [1, n] inclusive that do not appear in this array.
Could you do it without extra space and in O(n) runtime? You may
assume the returned list does not count as extra space.
Example:
Input:
[4,3,2,7,8,2,3,1]
Output:
[5,6]
My code is below - I think its O(N) but interviewer disagrees
def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
results_list=[]
for i in range(1,len(nums)+1):
if i not in nums:
results_list.append(i)
return results_list
You can implement an algorithm where you loop through each element of the list and set each element at index i to a negative integer if the list contains the element i as one of the values,. You can then add each index i which is positive to your list of missing items. It doesn't take any additional space and uses at the most 3 for loops(not nested), which makes the complexity O(3*n), which is basically O(n). This site explains it much better and also provides the source code.
edit- I have added the code in case someone wants it:
#The input list and the output list
input = [4, 5, 3, 3, 1, 7, 10, 4, 5, 3]
missing_elements = []
#Loop through each element i and set input[i - 1] to -input[i - 1]. abs() is necessary for
#this or it shows an error
for i in input:
if(input[abs(i) - 1] > 0):
input[abs(i) - 1] = -input[abs(i) - 1]
#Loop through the list again and append each positive value to output list
for i in range(0, len(input)):
if input[i] > 0:
missing_elements.append(i + 1)
For me using loops is not the best way to do it because loops increase the complexity of the given problem. You can try doing it with sets.
def findMissingNums(input_arr):
max_num = max(input_arr) # get max number from input list/array
input_set = set(input_arr) # convert input array into a set
set_num = set(range(1,max(input_arr)+1)) #create a set of all num from 1 to n (n is the max from the input array)
missing_nums = list(set_num - input_set) # take difference of both sets and convert to list/array
return missing_nums
input_arr = [4,3,2,7,8,2,3,1] # 1 <= input_arr[i] <= n
print(findMissingNums(input_arr)) # outputs [5 , 6]```
Use hash table, or dictionary in Python:
def findDisappearedNumbers(self, nums):
hash_table={}
for i in range(1,len(nums)+1):
hash_table[i] = False
for num in nums:
hash_table[num] = True
for i in range(1,len(nums)+1):
if not hash_table[i]:
print("missing..",i)
Try the following :
a=input() #[4,3,2,7,8,2,3,1]
b=[x for x in range(1,len(a)+1)]
c,d=set(a),set(b)
print(list(d-c))

How to find a pair of hunted values for a given value with lopps?

I am trying to write a function that gets a list of numbers and an integer and returns a tuple that containing pair of numbers from the list whose sum is the must closest to the number the function received.
for example: closest([10,22,28,29,30,40], 54) --> (22,30)
It is important for me to do this in loop and in time complexity of O(n).
The problem with my code is that the loop does not want to rerun the list end for any value I take from the beginning of the list...
I would appreciate help :)
Thanks for the helpers!
def closest(lst, x):
max_num = 0
cur = lst[0]
final = 0
my_tup = ()
for num in lst[::-1]:
max_num = cur + num
if max_num <= x:
if max_num > final:
final = max_num
my_tup = (cur, num)
else:
cur = lst[1]
return my_tup
print(closest([10,22,28,29,30,40], 54)) ---> return: (22,29)
The important part that you might not have noticed is that your input list is sorted.
10,22,28,29,30,40
Which means you can take advantage of this information to find the pair you're looking for in a single scan of the list. The intuition is that if you need a larger number, you can go towards the end of the list. These kind of solutions are referred to as the two-pointer technique
The problem you're trying to solve is a variant of the 2SUM problem. There are solutions online such as here
However I would suggest that you read through the first couple of links & try to solve it by yourself.
By using the itertools module and a dictionary where the keys are the sums of the pairs and the values are lists of pairs:
from itertools import combinations
def closest(lst, val):
d = {}
for element in combinations(lst, 2):
elem_sum = sum(element)
try:
d[elem_sum].append(element)
except KeyError:
d[elem_sum] = [element]
return d[min(d, key=lambda x: abs(x-val))]
>>> closest([10, 22, 28, 29, 30, 40], 54)
[(22, 30)]
If the list that you give is sorted and the elements are unique you can use this.Otherwise I believe that you can implement some conditions to the dictionary and get the values you want.
my_dict = {i+j:(i,j) for i in mylist for j in mylist if i != j and i + j < bound}
my_dict[max(t)]
Since you require tuples of exactly 2 elements this can be done with numpy to find the pair of points that are closest to x. Do the outer addition of the list with itself, find the closest absolute distance to x.
import numpy as np
def closest(lst, x):
arr = np.array(lst)
mat = np.abs(x - (arr[:, None] + arr)).astype(float)
mat[np.diag_indices_from(mat)] = np.NaN # Exclude tuples of same point with itself
i,j = np.unravel_index(np.nanargmin(mat), mat.shape)
return arr[i], arr[j]
closest([10,22,28,29,30,40], 54)
(22, 30)
closest([10,27,28,29,30,40], 54)
(27, 28)

Removing third element from list until there are less than 3 numbers

I have a problem. I need to create a list . And in every iteration i need to remove the third element and print the list without the deleted element.
The thing is. I'm trying to do an algorithm of deleting the third element without remove function or other inbuilt list functions. In my code I covered the following possibilities. If my list has less than 3 elements I print a message saying the list is short. If my list has 3 elements in it I will assign the third element the value of the second element and so on. My problem is when my list has more than 3 elements.
v=[] # list of numbers the user inputs
two=[] #list with only 2 elements
vector=[] # list with third element deleted when len(v)>3
def create_array():
n=int(input('Digit total elements in dynamic array - '))
for i in range(0,n):
element=int(input('Digit element to array - '))
v.append(element)
return v
print(create_array())
def remove_third_element():
for j in range(0,len(v)):
if len(v)<3: # if number of elements in list < 3 there is no element to delete
print('There is no element do delete! ')
return 0
elif len(v)==3:
v[2]==v[1] and v[1]==v[0]
two=[v[0],v[1]]
return two
else:
v[0]==v[1] and v[1]==v[2]
print(remove_third_element())
elif len(v) > 3:
ret = [];
for i in range(len(v)):
if(i != 2) ret.append(v[i]);
return ret
should do the trick
By the way, with this method you can remove you elif len(v) == 3
Also your code :
elif len(v)==3:
v[2]==v[1] and v[1]==v[0]
two=[v[0],v[1]]
return two
won't work because '==' is used as condition in python so it will return a boolean and not assign value.
go for
v[2] = v[1]
v[1] = v[0]
instead
Here's a Pythonic way of making a new list without the original list's third element.
new_list = old_list[:2] + old_list[3:]
old_list[:2] is shorthand for "until the 2-th index" (so we'll get index 0 and 1) of the old_list.
old_list[3:] is shorthand for, "from 3rd index 'til the end" (so index 3, 4, etc.).
Both return lists; in python, if you add lists, concatenation actually happens.
As an example, if old_list = [1,2,3,4,5], then new_list[:2] will be [1,2] and new_list[3:] will be [4,5]. So combining that will be [1,2,4,5].
Notice that this statement: v[2]==v[1] and v[1]==v[0] won't assign values!
Operation == return boolean.
Lets say your v looks like this: v = [1, 1, 3].
Then v[2]==v[1] and v[1]==v[0] gives you result: False and True, and this gives you reulst False. You can check it if you print this print(v[2]==v[1] and v[1]==v[0]).
If you want to assign values, you can use a statement like this: v[2], v[1] = v[1], v[0].
def main():
big_list = [ x for x in range(20) ]
while len(big_list) > 3:
big_list = big_list[:2] + big_list[3:]
print(big_list)

select first n items of a list without using a loop.

I know I can do this with a loop but I was wondering if there was a neater solution?
I have a list, which I want to select the first n items and place them in another list.
What I want to do is something like (pseudo code)
n = 3
x = [1,2,3,4,5,6,7,8,9,0]
y = copy n from x
print(y)
>>> [1,2,3]
Thanks
You can use slicing like this
y = x[:n]
print(y)
When you say x[:n], it means that, get all the elements till index n (but not including the element at index n).

Categories

Resources