I am trying to subtract every element in the list from the first lower value after it even if the lower value of the element is not in the next index
for example, I have the list [ 7,18,5,5,20,9,14,21,19]
it should produce [ 2,13,5,5,11,9,14,2,19]
for i in range(len(numeric_list)-2):
if numeric_list[i] >numeric_list[i+1]:
msg[i] = numeric_list[i] - numeric_list[i+1]
elif numeric_list [i]<numeric_list[i+1] and numeric_list[i]>numeric_list[i+2] :
msg[i]= numeric_list[i]-numeric_list[i+2]
else :
msg[i]=numeric_list[i]
I have used this code but the for loop skips the last two elements of the list, I tried to change the range of the loop but it gives me ' list out of range' because of the elif statement
I've modified the code and inserted few comments. Hope, it helps -
list1 = [ 7,18,5,5,20,9,14,21,19]
result= []
for index,i in enumerate(list1): # enumerate will provide index value which can be used for list slicing later
k=0 # flag this will check if the smaller number is available or not
for j in list1[index+1:]: # we need to take only those list items which comes after the element
if j < i :
result.append(i-j) # if number is found change the value of k and break the loop
k=1
break
if k ==0: # if the smaller number is not found don't change the value and insert the same number.
result.append(i)
print(result)
Here is a shorter solution (linewise) for Your issue:
list1 = [7, 18, 5, 5, 20, 9, 14, 21, 19]
result = [number - [value if value < number else 0 for value in list1[index + 1 if index + 1 < len(list1) else index:]][0] for index, number in enumerate(list1)]
print(result)
basically it is a complex list comprehension (never made anything this complex) but it works
I am trying an algorithm for a bubble sort and there is a part I don't understand
nums = [1,4,3,2,10,6,8,5]
for i in range (len(nums)-1,0,-1):
for j in range(i):
if nums[j] > nums[j+1]:
temp = nums[j]
nums[j] = nums[j+1]
nums[j+1] = temp
print(nums)
what does the numbers (-1,0,-1) mean in this part of the code (it dosent sort properly without it) v v v
for i in range (len(nums)-1,0,-1):
Syntax for range in python is -
range(start, end, step)
In your case, the looping is essentially starting from the last element(Index n-1) & moving towards the first element(Index 0) one step at a time.
Okey:
first one is starting point, second tells python where to stop, last one is step.
len(nums) - it gives you (durms..) length of this list, in our case it's 8,
len(nums)-1 - it's 8-1, we are doing this because when going through list python will start on number 0 and end at number 7(still 8 elements, but last one has index 7 not 8),
We will stop at 0, with step -1. So iteration will look like:
num[len(nums)-1] = num[7]
num[len(nums)-1-1] = num[6]
num[len(nums)-1-1-1] = num[5]
.....
num[len(nums)-1-1-1-1-1-1-1] = num[0]
I'm tryin to design a function that, given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A.
This code works fine yet has a high order of complexity, is there another solution that reduces the order of complexity?
Note: The 10000000 number is the range of integers in array A, I tried the sort function but does it reduces the complexity?
def solution(A):
for i in range(10000000):
if(A.count(i)) <= 0:
return(i)
The following is O(n logn):
a = [2, 1, 10, 3, 2, 15]
a.sort()
if a[0] > 1:
print(1)
else:
for i in range(1, len(a)):
if a[i] > a[i - 1] + 1:
print(a[i - 1] + 1)
break
If you don't like the special handling of 1, you could just append zero to the array and have the same logic handle both cases:
a = sorted(a + [0])
for i in range(1, len(a)):
if a[i] > a[i - 1] + 1:
print(a[i - 1] + 1)
break
Caveats (both trivial to fix and both left as an exercise for the reader):
Neither version handles empty input.
The code assumes there no negative numbers in the input.
O(n) time and O(n) space:
def solution(A):
count = [0] * len(A)
for x in A:
if 0 < x <= len(A):
count[x-1] = 1 # count[0] is to count 1
for i in range(len(count)):
if count[i] == 0:
return i+1
return len(A)+1 # only if A = [1, 2, ..., len(A)]
This should be O(n). Utilizes a temporary set to speed things along.
a = [2, 1, 10, 3, 2, 15]
#use a set of only the positive numbers for lookup
temp_set = set()
for i in a:
if i > 0:
temp_set.add(i)
#iterate from 1 upto length of set +1 (to ensure edge case is handled)
for i in range(1, len(temp_set) + 2):
if i not in temp_set:
print(i)
break
My proposal is a recursive function inspired by quicksort.
Each step divides the input sequence into two sublists (lt = less than pivot; ge = greater or equal than pivot) and decides, which of the sublists is to be processed in the next step. Note that there is no sorting.
The idea is that a set of integers such that lo <= n < hi contains "gaps" only if it has less than (hi - lo) elements.
The input sequence must not contain dups. A set can be passed directly.
# all cseq items > 0 assumed, no duplicates!
def find(cseq, cmin=1):
# cmin = possible minimum not ruled out yet
size = len(cseq)
if size <= 1:
return cmin+1 if cmin in cseq else cmin
lt = []
ge = []
pivot = cmin + size // 2
for n in cseq:
(lt if n < pivot else ge).append(n)
return find(lt, cmin) if cmin + len(lt) < pivot else find(ge, pivot)
test = set(range(1,100))
print(find(test)) # 100
test.remove(42)
print(find(test)) # 42
test.remove(1)
print(find(test)) # 1
Inspired by various solutions and comments above, about 20%-50% faster in my (simplistic) tests than the fastest of them (though I'm sure it could be made faster), and handling all the corner cases mentioned (non-positive numbers, duplicates, and empty list):
import numpy
def firstNotPresent(l):
positive = numpy.fromiter(set(l), dtype=int) # deduplicate
positive = positive[positive > 0] # only keep positive numbers
positive.sort()
top = positive.size + 1
if top == 1: # empty list
return 1
sequence = numpy.arange(1, top)
try:
return numpy.where(sequence < positive)[0][0]
except IndexError: # no numbers are missing, top is next
return top
The idea is: if you enumerate the positive, deduplicated, sorted list starting from one, the first time the index is less than the list value, the index value is missing from the list, and hence is the lowest positive number missing from the list.
This and the other solutions I tested against (those from adrtam, Paritosh Singh, and VPfB) all appear to be roughly O(n), as expected. (It is, I think, fairly obvious that this is a lower bound, since every element in the list must be examined to find the answer.) Edit: looking at this again, of course the big-O for this approach is at least O(n log(n)), because of the sort. It's just that the sort is so fast comparitively speaking that it looked linear overall.
The idea is for each number to add the next sequential numbers to try to reach the target value. If for each starting value (for i...) if adding the next sequential numbers exceeds the target then i has failed and move onto the next.
I'm getting some values slipping through and some duplicating.
If the targets intentionally match the lists it works fine; I've noticed 13 throws up some strange behaviour.
def addToTarget (mylist, target):
solutions_list = []
for i in range(0,len(mylist)):
#set base values
total = mylist[i]
counter = i
solutions = []
solutions.append(total)
if total == target:
solutions_list.append(solutions) # first value matches immediately
elif total > target:
solutions_list.append([counter-1, "first value already too high"])
elif counter == (len(mylist)):
solutions_list.append("caught as final value ")
while total < target and counter < (len(mylist)-1):
counter +=1
value = mylist[counter]
total += value
solutions.append(value)
if total == target:
solutions_list.append([counter, solutions])
elif total > target:
solutions_list.append([counter-1, "total > target during"])
elif counter == (len(mylist)-1):
solutions_list.append([counter-1, "total < target - came to end of list "])
else : solutions_list.append([counter-1, "not sure but certian values seem to slip through"])
return solutions_list
mylist = [5, 5, 3, 10, 2, 8, 10]
solutions_list = []
test = answer(mylist, 13)
for i in test : print(i)
You could use two markers that move through the list and keep track of sum of values between them. While current sum is less than target (13) and first marker is not at the end of the list move it forward and add value to current sum. Once first marker has been moved check if the current sum matches the target and update result accordingly. In final step move second marker forward one step and subtract item that it pointed to from current sum.
l = [5, 5, 3, 10, 2, 8, 10]
TARGET = 13
res = []
end = 0
current = 0
for start in range(len(l)):
while current < TARGET and end < len(l):
current += l[end]
end += 1
res.append(l[start:end] if current == TARGET else 'fail')
current -= l[start]
print(res)
Output:
[[5, 5, 3], 'fail', [3, 10], 'fail', 'fail', 'fail', 'fail']
Your code and your problem statement would benefit from rewriting as a sequence of small, self-contained, painfully obvious steps.
As far as I could understand, you take a list of numbers xs and look for values of i such that xs[i] + xs[i + 1] == target.
So, let's first generate a list of triples (i, x[i], x[i + 1]), then scan it for solutions.
An explicit way:
def pairs(xs):
for i in range(len(xs) - 1):
yield (i, xs[i], xs[i + 1])
A one-line way, fine for reasonably short lists:
def pairs(xs):
return zip(range(len(xs)), xs, xs[1:])
Now find the matches:
matches = [(i, x0, x1) for (i, x0, x1) if x0 + x1 == target]
We don't mark the various conditions of mismatches, though. Tese can be added if the list comprehension above is converted into an explicit loop.
Hope this helps.
This may seem like a simple question but when I attempted to implement selection sort in Python, I do not get a sorted list. Is there something wrong with my implementation? The subsetting may be a problem.
source = [4,2,1,10,5,3,100]
for i in range(len(source)):
mini = min(source[i:]) #find minimum element
min_index = source[i:].index(mini)-1 #find index of minimum element
source[i:][min_index]= source[i:][0] #replace element at min_index with first element
source[i:][0] = mini #replace first element with min element
print source
I think there were a couple issues.
First, when your do source[i:], I believe that returns a new array of the sub-elements requested and not part of the original array, thus if you modify it, your don't modify the original. Second, you were subtracting 1 from an index when you shouldn't.
source = [4,2,1,10,5,3,100]
for i in range(len(source)):
mini = min(source[i:]) #find minimum element
min_index = source[i:].index(mini) #find index of minimum element
source[i + min_index] = source[i] #replace element at min_index with first element
source[i] = mini #replace first element with min element
print source
This gives:
[1, 2, 3, 4, 5, 10, 100]
Here is how I would rewrite your code. Of course in Python I would just use list.sort() to sort a list, but here is a selection sort in Python.
We make a generator expression that returns tuples of (value, i) for a value and its index from the list. Then when min() evaluates to find minimum, it finds the lowest tuple value; since the value comes first in the tuple before the index, the value will be the important part, and min() will find the lowest value. (If there is a tie, min() will use the second part of the tuple, the index, as a tie-breaker. But for sort we don't care how ties are broken.)
Now, instead of searching through the sub-list to find the min value, and then searching through it again to figure out the index, we search through it once and get both min value and index.
But we don't actually care about the min value; we care about the index. So after min() is done, we just throw away the actual value but keep the index. Adjust the index to be correct in the whole list (not in the slice of the list) and then we can swap.
We use the standard Python idiom for swapping two values. Python will build a tuple object to be the intermediate, then unpack this tuple into the left-hand-side.
lst = [4,2,1,10,5,3,100]
for i_sortpos in range(len(lst)):
# Make a generator expression to return (value, i) pairs.
genexp = ((n, i) for i, n in enumerate(lst[i_sortpos:]))
# Use genexp with min() to find lowest and its index.
# (Use '_' for variable name for the actual value; we don't use it.)
_, i_min = min(genexp)
# Adjust index to be correct in full list.
i_min += i_sortpos
# Swap the number at i_sortpos with the lowest found.
lst[i_sortpos], lst[i_min] = lst[i_min], lst[i_sortpos]
print(lst)
EDIT: And here is a refinement of the above. A slice from a list actually allocates a new list; our code here doesn't need a new list, it just needs a convenient way to examine a sublist. The itertools module offers a function, islice(), that returns an iterator that iterates over a slice of a list. This avoids repeatedly creating and destroying lists as we examine each sublist.
I believe this is the most efficient way to do selection sort in Python. (You could get rid of the part where we bind the generator expression to the name genexp and save a few microseconds... just make the call to min() a long one-liner. But it's not really worth the loss of readability.)
import itertools as it
lst = [4,2,1,10,5,3,100]
for i_sortpos in range(len(lst)):
# Make a generator expression to return (value, i) pairs.
# Use it.islice() for to look at sublist.
genexp = ((n, i) for i, n in enumerate(it.islice(lst, i_sortpos, len(lst))))
# Use genexp with min() to find lowest and its index.
# (Use '_' for variable name for the actual value; we don't use it.)
_, i_min = min(genexp)
# Adjust index to be correct in full list.
i_min += i_sortpos
# Swap the number at i_sortpos with the lowest found.
lst[i_sortpos], lst[i_min] = lst[i_min], lst[i_sortpos]
print(lst)
def selectionSort(List_):
for i in range(len(List_)):`
#track the current smallest value
smallIndex = i
#loop from the current smallest value
for j in range(i+1,len(List_))
if List_[j] < List_[smallIndex]:
#if new value is less that our smallest value,change
#smallest value to this
smallIndex = j
if smallIndex != i:
#swap the values
List_[smallIndex],List_[i] = List_[i],List_[smallIndex]
#return sorted list
return List_
def ss(l):
for i in range(0,len(l)):
d=l.index(min(l[i:]))
c=l[i]
l[i]=min(l[i:])
l[d]=c
print(l) #it prints each step of selection sort
y=[10,9,1,5,0,6]
ss(y)
def selSort(L):
"""
Find the smallest element in the list and put it (swap it) in the first location,
Find the second element and put it (swap it) in the second locaiton, and so on.
"""
for i in range(len(L) - 1):
minIndx = i
minVal= L[i]
j = i + 1
while j < len(L):
if minVal > L[j]:
minIndx = j
minVal= L[j]
j += 1
temp = L[i]
L[i] = L[minIndx]
L[minIndx] = temp
return L
Call:
print( selSort([120,11,0,1,3,2,3,4,5,6,7,8,9,10]) )
Output
[0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 120]
s = [1,8,4,9,3,6,2]
for i in range(len(s)):
maxi = max(s[0:len(s)-i]) #find max element
tempi = s.index(maxi) # find index of max element
temp = s[len(s)-1-i] #assign last element as temp
s[len(s)-1-i] = maxi #put max element in last position
s[tempi] = temp # put the element initially at last in its new
print s
Find the position(first and last), swap the elements if last is lower.
nums = [4,2,1,10,5,3,100]
def sort(nums):
###Find the position and now first 0th element is sorted and rest is unsorted
#Second iteration first 2 element is sorted
for i in range(len(nums)-1):
miniposition = i
for j in range(i,len(nums)):
if nums[j] < nums[miniposition]:
miniposition = j
temp = nums[i]
nums[i] = nums[miniposition]
nums[miniposition] = temp
sort(nums)
print (nums)
First iteration(swapped 4 and 1)
[1, 2, 4, 10, 5, 3, 100]
[1, 2, 4, 10, 5, 3, 100]
[1, 2, 3, 10, 5, 4, 100]
[1, 2, 3, 4, 5, 10, 100]
[1, 2, 3, 4, 5, 10, 100]
[1, 2, 3, 4, 5, 10, 100]
Other way
nums = [4,2,1,10,5,3,100]
i = 0
while i<len(nums):
#smallest element in the sublist
smallest = min(nums[i:])
#index of smallest element
index_of_smallest = nums.index(smallest)
#swapping
nums[i],nums[index_of_smallest] = nums[index_of_smallest],nums[i]
i=i+1
print (nums)
a slight variation of the solution provided
def selection_sort(l):
i = 0
while i < len(l):
minium_value = min(l[i:]) # minium value at ith iteration
minium_value_index = l[i:].index(minium_value) # minium value index at i th iteration
if minium_value < l[i]: # if the current value already min, skip
l[i + minium_value_index] = l[i] # put current value in min value's index - swap 1
l[i] = minium_value # set current value with min value- swap 2
i += 1
return l
def selection_sort_min(): # sorting number
for i in range(len(num)-1):
current_min_index = i
for j in range(i+1,len(num)):
if num[j] < num[current_min_index] :
current_min_index = j
num[i],num[current_min_index] = num [current_min_index],num[i]
print(num)
num = [23,89,12,0,3,7,33]
selection_sort_min()
here is what I think is a good way to sort a list of numbers and I hope it helps:
list=[5,4,3,1,6,8,10,9]
listsorted=[]
for i in range(len(list)):
x=min(list)
list.remove(x)
listsorted.append(x)
print listsorted
and the result will be [1, 3, 4, 5, 6, 8, 9, 10]
I think the "accepted" answer here is unhelpful. If we look at e.g.
mini = min(source[i:]) #find minimum element
min_index = source[i:].index(mini) #find index of minimum element
not only is this inefficient in terms of creating list slices unnecessarily, but they are searched unnecessarily. It's reasonably concise but I don't think it's the best solution.
def Selection_Sort(Sarray):
length = len(Sarray)
i = 0
j = 0
for i in range(length):
j = i+1
for j in range(length):
if Sarray[i] < Sarray[j]
t = Sarray[i]
Sarray[i] = Sarray[j]
Sarray[j] = t
j = j+1
i = i+1
return Sarray
Code of select sort from MIT online course .
def selSort(L):
for i in range(len(L) - 1):
minIndx = i
minVal = L[i]
j = i+1
while j < len(L):
if minVal > L[j]:
minIndx = j
minVal = L[j]
j += 1
if minIndx != i:
temp = L[i]
L[i] = L[minIndx]
L[minIndx] = temp
def selectSort(L):
for i in range(len(L)):
print L
minIndex = i
minValue = L[i]
j = i + 1
while j < len(L):
if minValue > L[j]:
minIndex = j
minValue = L[j]
j +=1
temp = L[i]
L[i] = L[minIndex]
L[minIndex] = temp