Related
I am trying to implement the binary search in python and have written it as follows. However, I can't make it stop whenever needle_element is larger than the largest element in the array.
Can you help? Thanks.
def binary_search(array, needle_element):
mid = (len(array)) / 2
if not len(array):
raise "Error"
if needle_element == array[mid]:
return mid
elif needle_element > array[mid]:
return mid + binary_search(array[mid:],needle_element)
elif needle_element < array[mid]:
return binary_search(array[:mid],needle_element)
else:
raise "Error"
It would be much better to work with a lower and upper indexes as Lasse V. Karlsen was suggesting in a comment to the question.
This would be the code:
def binary_search(array, target):
lower = 0
upper = len(array)
while lower < upper: # use < instead of <=
x = lower + (upper - lower) // 2
val = array[x]
if target == val:
return x
elif target > val:
if lower == x: # these two are the actual lines
break # you're looking for
lower = x
elif target < val:
upper = x
lower < upper will stop once you have reached the smaller number (from the left side)
if lower == x: break will stop once you've reached the higher number (from the right side)
Example:
>>> binary_search([1,5,8,10], 5) # return 1
1
>>> binary_search([1,5,8,10], 0) # return None
>>> binary_search([1,5,8,10], 15) # return None
Why not use the bisect module? It should do the job you need---less code for you to maintain and test.
array[mid:] creates a new sub-copy everytime you call it = slow. Also you use recursion, which in Python is slow, too.
Try this:
def binarysearch(sequence, value):
lo, hi = 0, len(sequence) - 1
while lo <= hi:
mid = (lo + hi) // 2
if sequence[mid] < value:
lo = mid + 1
elif value < sequence[mid]:
hi = mid - 1
else:
return mid
return None
In the case that needle_element > array[mid], you currently pass array[mid:] to the recursive call. But you know that array[mid] is too small, so you can pass array[mid+1:] instead (and adjust the returned index accordingly).
If the needle is larger than all the elements in the array, doing it this way will eventually give you an empty array, and an error will be raised as expected.
Note: Creating a sub-array each time will result in bad performance for large arrays. It's better to pass in the bounds of the array instead.
You can improve your algorithm as the others suggested, but let's first look at why it doesn't work:
You're getting stuck in a loop because if needle_element > array[mid], you're including element mid in the bisected array you search next. So if needle is not in the array, you'll eventually be searching an array of length one forever. Pass array[mid+1:] instead (it's legal even if mid+1 is not a valid index), and you'll eventually call your function with an array of length zero. So len(array) == 0 means "not found", not an error. Handle it appropriately.
This is a tail recursive solution, I think this is cleaner than copying partial arrays and then keeping track of the indexes for returning:
def binarySearch(elem, arr):
# return the index at which elem lies, or return false
# if elem is not found
# pre: array must be sorted
return binarySearchHelper(elem, arr, 0, len(arr) - 1)
def binarySearchHelper(elem, arr, start, end):
if start > end:
return False
mid = (start + end)//2
if arr[mid] == elem:
return mid
elif arr[mid] > elem:
# recurse to the left of mid
return binarySearchHelper(elem, arr, start, mid - 1)
else:
# recurse to the right of mid
return binarySearchHelper(elem, arr, mid + 1, end)
def binary_search(array, target):
low = 0
mid = len(array) / 2
upper = len(array)
if len(array) == 1:
if array[0] == target:
print target
return array[0]
else:
return False
if target == array[mid]:
print array[mid]
return mid
else:
if mid > low:
arrayl = array[0:mid]
binary_search(arrayl, target)
if upper > mid:
arrayu = array[mid:len(array)]
binary_search(arrayu, target)
if __name__ == "__main__":
a = [3,2,9,8,4,1,9,6,5,9,7]
binary_search(a,9)
Using Recursion:
def binarySearch(arr,item):
c = len(arr)//2
if item > arr[c]:
ans = binarySearch(arr[c+1:],item)
if ans:
return binarySearch(arr[c+1],item)+c+1
elif item < arr[c]:
return binarySearch(arr[:c],item)
else:
return c
binarySearch([1,5,8,10,20,50,60],10)
All the answers above are true , but I think it would help to share my code
def binary_search(number):
numbers_list = range(20, 100)
i = 0
j = len(numbers_list)
while i < j:
middle = int((i + j) / 2)
if number > numbers_list[middle]:
i = middle + 1
else:
j = middle
return 'the index is '+str(i)
If you're doing a binary search, I'm guessing the array is sorted. If that is true you should be able to compare the last element in the array to the needle_element. As octopus says, this can be done before the search begins.
You can just check to see that needle_element is in the bounds of the array before starting at all. This will make it more efficient also, since you won't have to do several steps to get to the end.
if needle_element < array[0] or needle_element > array[-1]:
# do something, raise error perhaps?
It returns the index of key in array by using recursive.
round() is a function convert float to integer and make code fast and goes to expected case[O(logn)].
A=[1,2,3,4,5,6,7,8,9,10]
low = 0
hi = len(A)
v=3
def BS(A,low,hi,v):
mid = round((hi+low)/2.0)
if v == mid:
print ("You have found dude!" + " " + "Index of v is ", A.index(v))
elif v < mid:
print ("Item is smaller than mid")
hi = mid-1
BS(A,low,hi,v)
else :
print ("Item is greater than mid")
low = mid + 1
BS(A,low,hi,v)
BS(A,low,hi,v)
Without the lower/upper indexes this should also do:
def exists_element(element, array):
if not array:
yield False
mid = len(array) // 2
if element == array[mid]:
yield True
elif element < array[mid]:
yield from exists_element(element, array[:mid])
else:
yield from exists_element(element, array[mid + 1:])
Returning a boolean if the value is in the list.
Capture the first and last index of the list, loop and divide the list capturing the mid value.
In each loop will do the same, then compare if value input is equal to mid value.
def binarySearch(array, value):
array = sorted(array)
first = 0
last = len(array) - 1
while first <= last:
midIndex = (first + last) // 2
midValue = array[midIndex]
if value == midValue:
return True
if value < midValue:
last = midIndex - 1
if value > midValue:
first = midIndex + 1
return False
I have been trying to implement merge sort but I keep running into a "Maximum Recursion Depth" error. My current theory is that "if listlen <= 1:" isn't catching it but I can't figure out why
def mergesort(listin):
listlen = len(listin)
if listlen <= 1:
return listin
left = []
right = []
i = 0
while i < listlen:
if i <= listlen / 2:
left.append(listin[i])
else:
right.append(listin[i])
i += 1
left = mergesort(left)
right = mergesort(right)
return merge(left, right)
def merge(listlef, listrig):
result = []
while len(listlef) != 0 and len(listrig) != 0:
if listlef[0] <= listrig[0]:
result.append(listlef[0])
listlef = listlef[1:]
else:
result.append(listrig[0])
listrig = listrig[1:]
while len(listlef) != 0:
result.append(listlef[0])
listlef = listlef[1:]
while len(listrig) != 0:
result.append(listrig[0])
listrig = listrig[1:]
return result
For a list of size 2, note that i will only be 0 and 1, both of which are less than or equal to 2/1 == 1.
Instead of fiddling with indices, though, just alternate which list you append to:
left = []
right = []
for item in listin:
left.append(item)
left, right = right, left
I am trying to write a function that will not only determine whether the sum of a subset of a set adds to a desired target number, but also to print the subset that is the solution.
Here is my code for finding whether a subset exists:
def subsetsum(array,num):
if num == 0 or num < 1:
return False
elif len(array) == 0:
return False
else:
if array[0] == num:
return True
else:
return subsetsum(array[1:],(num - array[0])) or subsetsum(array[1:],num)
How can I modify this to record the subset itself so that I can print it? Thanks in advance!
Based on your solution:
def subsetsum(array,num):
if num == 0 or num < 1:
return None
elif len(array) == 0:
return None
else:
if array[0] == num:
return [array[0]]
else:
with_v = subsetsum(array[1:],(num - array[0]))
if with_v:
return [array[0]] + with_v
else:
return subsetsum(array[1:],num)
Modification to also detect duplicates and further solutions when a match happened
def subset(array, num):
result = []
def find(arr, num, path=()):
if not arr:
return
if arr[0] == num:
result.append(path + (arr[0],))
else:
find(arr[1:], num - arr[0], path + (arr[0],))
find(arr[1:], num, path)
find(array, num)
return result
You could change your approach to do that more easily, something like:
def subsetsum(array, num):
if sum(array) == num:
return array
if len(array) > 1:
for subset in (array[:-1], array[1:]):
result = subsetsum(subset, num)
if result is not None:
return result
This will return either a valid subset or None.
Thought I'll throw another solution into the mix.
We can map each selection of a subset of the list to a (0-padded) binary number, where a 0 means not taking the member in the corresponsing position in the list, and 1 means taking it.
So masking [1, 2, 3, 4] with 0101 creates the sub-list [2, 4].
So, by generating all 0-padded binary numbers in the range between 0 and 2^LENGTH_OF_LIST, we can iterate all selections. If we use these sub-list selections as masks and sum the selection - we can know the answer.
This is how it's done:
#!/usr/bin/env python
# use a binary number (represented as string) as a mask
def mask(lst, m):
# pad number to create a valid selection mask
# according to definition in the solution laid out
m = m.zfill(len(lst))
return map(lambda x: x[0], filter(lambda x: x[1] != '0', zip(lst, m)))
def subset_sum(lst, target):
# there are 2^n binary numbers with length of the original list
for i in xrange(2**len(lst)):
# create the pick corresponsing to current number
pick = mask(lst, bin(i)[2:])
if sum(pick) == target:
return pick
return False
print subset_sum([1,2,3,4,5], 7)
Output:
[3, 4]
To return all possibilities we can use a generator instead (the only changes are in subset_sum, using yield instead of return and removing return False guard):
#!/usr/bin/env python
# use a binary number (represented as string) as a mask
def mask(lst, m):
# pad number to create a valid selection mask
# according to definition in the solution laid out
m = m.zfill(len(lst))
return map(lambda x: x[0], filter(lambda x: x[1] != '0', zip(lst, m)))
def subset_sum(lst, target):
# there are 2^n binary numbers with length of the original list
for i in xrange(2**len(lst)):
# create the pick corresponsing to current number
pick = mask(lst, bin(i)[2:])
if sum(pick) == target:
yield pick
# use 'list' to unpack the generator
print list(subset_sum([1,2,3,4,5], 7))
Output:
[[3, 4], [2, 5], [1, 2, 4]]
Note: While not padding the mask with zeros may work as well, as it will simply select members of the original list in a reverse order - I haven't checked it and didn't use it.
I didn't use it since it's less obvious (to me) what's going on with such trenary-like mask (1, 0 or nothing) and I rather have everything well defined.
Slightly updated the below code to return all possible combinations for this problem. Snippet in the thread above will not print all possible combinations when the input is given as subset([4,3,1],4)
def subset(array, num):
result = []
def find(arr, num, path=()):
if not arr:
return
if arr[0] == num:
result.append(path + (arr[0],))
else:
find(arr[1:], num - arr[0], path + (arr[0],))
find(arr[1:], num, path)
find(array, num)
return result
A bit different approach to print all subset through Recursion.
def subsetSumToK(arr,k):
if len(arr)==0:
if k == 0:
return [[]]
else:
return []
output=[]
if arr[0]<=k:
temp2=subsetSumToK(arr[1:],k-arr[0]) #Including the current element
if len(temp2)>0:
for i in range(len(temp2)):
temp2[i].insert(0,arr[0])
output.append(temp2[i])
temp1=subsetSumToK(arr[1:],k) #Excluding the current element
if len(temp1)>0:
for i in range(len(temp1)):
output.append(temp1[i])
return output
arr=[int(i) for i in input().split()]
k=int(input())
sub=subsetSumToK(arr,k)
for i in sub:
for j in range(len(i)):
if j==len(i)-1:
print(i[j])
else:
print(i[j],end=" ")
Rather than using recursion, you could use the iterative approach.
def desiredSum(array, sum):
numberOfItems = len(array)
storage = [[0 for x in range(sum + 1)] for x in range(numberOfItems + 1)]
for i in range(numberOfItems + 1):
for j in range(sum + 1):
value = array[i - 1]
if i is 0: storage[i][j] = 0
if j is 0: storage[i][j] = 1
if value <= j:
noTake = storage[i - 1][j]
take = storage[i - 1][j - value]
storage[i][j] = noTake + take
return storage[numberOfItems][sum]
In class we are doing sorting algorithms and, although I understand them fine when talking about them and writing pseudocode, I am having problems writing actual code for them.
This is my attempt in Python:
mylist = [12, 5, 13, 8, 9, 65]
def bubble(badList):
length = len(badList) - 1
unsorted = True
while unsorted:
for element in range(0,length):
unsorted = False
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
print badList
else:
unsorted = True
print bubble(mylist)
Now, this (as far as I can tell) sorts correctly, but once it finishes it just loops indefinitely.
How can this code be fixed so the function finishes properly and correctly sorts a list of any (reasonable) size?
P.S. I know I should not really have prints in a function and I should have a return, but I just have not done that yet as my code does not really work yet.
To explain why your script isn't working right now, I'll rename the variable unsorted to sorted.
At first, your list isn't yet sorted. Of course, we set sorted to False.
As soon as we start the while loop, we assume that the list is already sorted. The idea is this: as soon as we find two elements that are not in the right order, we set sorted back to False. sorted will remain True only if there were no elements in the wrong order.
sorted = False # We haven't started sorting yet
while not sorted:
sorted = True # Assume the list is now sorted
for element in range(0, length):
if badList[element] > badList[element + 1]:
sorted = False # We found two elements in the wrong order
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
# We went through the whole list. At this point, if there were no elements
# in the wrong order, sorted is still True. Otherwise, it's false, and the
# while loop executes again.
There are also minor little issues that would help the code be more efficient or readable.
In the for loop, you use the variable element. Technically, element is not an element; it's a number representing a list index. Also, it's quite long. In these cases, just use a temporary variable name, like i for "index".
for i in range(0, length):
The range command can also take just one argument (named stop). In that case, you get a list of all the integers from 0 to that argument.
for i in range(length):
The Python Style Guide recommends that variables be named in lowercase with underscores. This is a very minor nitpick for a little script like this; it's more to get you accustomed to what Python code most often resembles.
def bubble(bad_list):
To swap the values of two variables, write them as a tuple assignment. The right hand side gets evaluated as a tuple (say, (badList[i+1], badList[i]) is (3, 5)) and then gets assigned to the two variables on the left hand side ((badList[i], badList[i+1])).
bad_list[i], bad_list[i+1] = bad_list[i+1], bad_list[i]
Put it all together, and you get this:
my_list = [12, 5, 13, 8, 9, 65]
def bubble(bad_list):
length = len(bad_list) - 1
sorted = False
while not sorted:
sorted = True
for i in range(length):
if bad_list[i] > bad_list[i+1]:
sorted = False
bad_list[i], bad_list[i+1] = bad_list[i+1], bad_list[i]
bubble(my_list)
print my_list
(I removed your print statement too, by the way.)
The goal of bubble sort is to move the heavier items at the bottom in each round, while moving the lighter items up. In the inner loop, where you compare the elements, you don't have to iterate the whole list in each turn. The heaviest is already placed last. The swapped variable is an extra check so we can mark that the list is now sorted and avoid continuing with unnecessary calculations.
def bubble(badList):
length = len(badList)
for i in range(0,length):
swapped = False
for element in range(0, length-i-1):
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
swapped = True
if not swapped: break
return badList
Your version 1, corrected:
def bubble(badList):
length = len(badList) - 1
unsorted = True
while unsorted:
unsorted = False
for element in range(0,length):
#unsorted = False
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
unsorted = True
#print badList
#else:
#unsorted = True
return badList
This is what happens when you use variable name of negative meaning, you need to invert their values. The following would be easier to understand:
sorted = False
while not sorted:
...
On the other hand, the logic of the algorithm is a little bit off. You need to check whether two elements swapped during the for loop. Here's how I would write it:
def bubble(values):
length = len(values) - 1
sorted = False
while not sorted:
sorted = True
for element in range(0,length):
if values[element] > values[element + 1]:
hold = values[element + 1]
values[element + 1] = values[element]
values[element] = hold
sorted = False
return values
Your use of the Unsorted variable is wrong; you want to have a variable that tells you if you have swapped two elements; if you have done that, you can exit your loop, otherwise, you need to loop again. To fix what you've got here, just put the "unsorted = false" in the body of your if case; remove your else case; and put "unsorted = true before your for loop.
def bubble_sort(l):
for passes_left in range(len(l)-1, 0, -1):
for index in range(passes_left):
if l[index] < l[index + 1]:
l[index], l[index + 1] = l[index + 1], l[index]
return l
#A very simple function, can be optimized (obviously) by decreasing the problem space of the 2nd array. But same O(n^2) complexity.
def bubble(arr):
l = len(arr)
for a in range(l):
for b in range(l-1):
if (arr[a] < arr[b]):
arr[a], arr[b] = arr[b], arr[a]
return arr
You've got a couple of errors in there. The first is in length, and the second is in your use of unsorted (as stated by McWafflestix). You probably also want to return the list if you're going to print it:
mylist = [12, 5, 13, 8, 9, 65]
def bubble(badList):
length = len(badList) - 2
unsorted = True
while unsorted:
for element in range(0,length):
unsorted = False
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
print badList
unsorted = True
return badList
print bubble(mylist)
eta: You're right, the above is buggy as hell. My bad for not testing through some more examples.
def bubble2(badList):
swapped = True
length = len(badList) - 2
while swapped:
swapped = False
for i in range(0, length):
if badList[i] > badList[i + 1]:
# swap
hold = badList[i + 1]
badList[i + 1] = badList[i]
badList[i] = hold
swapped = True
return badList
I am a fresh fresh beginner, started to read about Python yesterday.
Inspired by your example I created something maybe more in the 80-ties style, but nevertheless it kinda works
lista1 = [12, 5, 13, 8, 9, 65]
i=0
while i < len(lista1)-1:
if lista1[i] > lista1[i+1]:
x = lista1[i]
lista1[i] = lista1[i+1]
lista1[i+1] = x
i=0
continue
else:
i+=1
print(lista1)
The problem with the original algorithm is that if you had a lower number further in the list, it would not bring it to the correct sorted position. The program needs to go back the the beginning each time to ensure that the numbers sort all the way through.
I simplified the code and it will now work for any list of numbers regardless of the list and even if there are repeating numbers. Here's the code
mylist = [9, 8, 5, 4, 12, 1, 7, 5, 2]
print mylist
def bubble(badList):
length = len(badList) - 1
element = 0
while element < length:
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
element = 0
print badList
else:
element = element + 1
print bubble(mylist)
def bubble_sort(l):
exchanged = True
iteration = 0
n = len(l)
while(exchanged):
iteration += 1
exchanged = False
# Move the largest element to the end of the list
for i in range(n-1):
if l[i] > l[i+1]:
exchanged = True
l[i], l[i+1] = l[i+1], l[i]
n -= 1 # Largest element already towards the end
print 'Iterations: %s' %(iteration)
return l
def bubbleSort(alist):
if len(alist) <= 1:
return alist
for i in range(0,len(alist)):
print "i is :%d",i
for j in range(0,i):
print "j is:%d",j
print "alist[i] is :%d, alist[j] is :%d"%(alist[i],alist[j])
if alist[i] > alist[j]:
alist[i],alist[j] = alist[j],alist[i]
return alist
alist = [54,26,93,17,77,31,44,55,20,-23,-34,16,11,11,11]
print bubbleSort(alist)
def bubble_sort(a):
t = 0
sorted = False # sorted = False because we have not began to sort
while not sorted:
sorted = True # Assume sorted = True first, it will switch only there is any change
for key in range(1,len(a)):
if a[key-1] > a[key]:
sorted = False
t = a[key-1]; a[key-1] = a[key]; a[key] = t;
print a
A simpler example:
a = len(alist)-1
while a > 0:
for b in range(0,a):
#compare with the adjacent element
if alist[b]>=alist[b+1]:
#swap both elements
alist[b], alist[b+1] = alist[b+1], alist[b]
a-=1
This simply takes the elements from 0 to a(basically, all the unsorted elements in that round) and compares it with its adjacent element, and making a swap if it is greater than its adjacent element. At the end the round, the last element is sorted, and the process runs again without it, until all elements have been sorted.
There is no need for a condition whether sort is true or not.
Note that this algorithm takes into consideration the position of the numbers only when swapping, so repeated numbers will not affect it.
PS. I know it has been very long since this question was posted, but I just wanted to share this idea.
def bubble_sort(li):
l = len(li)
tmp = None
sorted_l = sorted(li)
while (li != sorted_l):
for ele in range(0,l-1):
if li[ele] > li[ele+1]:
tmp = li[ele+1]
li[ele+1] = li [ele]
li[ele] = tmp
return li
def bubbleSort ( arr ):
swapped = True
length = len ( arr )
j = 0
while swapped:
swapped = False
j += 1
for i in range ( length - j ):
if arr [ i ] > arr [ i + 1 ]:
# swap
tmp = arr [ i ]
arr [ i ] = arr [ i + 1]
arr [ i + 1 ] = tmp
swapped = True
if __name__ == '__main__':
# test list
a = [ 67, 45, 39, -1, -5, -44 ];
print ( a )
bubbleSort ( a )
print ( a )
def bubblesort(array):
for i in range(len(array)-1):
for j in range(len(array)-1-i):
if array[j] > array[j+1]:
array[j], array[j+1] = array[j+1], array[j]
return(array)
print(bubblesort([3,1,6,2,5,4]))
arr = [5,4,3,1,6,8,10,9] # array not sorted
for i in range(len(arr)):
for j in range(i, len(arr)):
if(arr[i] > arr[j]):
arr[i], arr[j] = arr[j], arr[i]
print (arr)
I consider adding my solution because ever solution here is having
greater time
greater space complexity
or doing too much operations
then is should be
So, here is my solution:
def countInversions(arr):
count = 0
n = len(arr)
for i in range(n):
_count = count
for j in range(0, n - i - 1):
if arr[j] > arr[j + 1]:
count += 1
arr[j], arr[j + 1] = arr[j + 1], arr[j]
if _count == count:
break
return count
If anyone is interested in a shorter implementation using a list comprehension:
def bubble_sort(lst: list) -> None:
[swap_items(lst, i, i+1) for left in range(len(lst)-1, 0, -1) for i in range(left) if lst[i] > lst[i+1]]
def swap_items(lst: list, pos1: int, pos2: int) -> None:
lst[pos1], lst[pos2] = lst[pos2], lst[pos1]
Here is a different variation of bubble sort without for loop. Basically you are considering the lastIndex of the array and slowly decrementing it until it first index of the array.
The algorithm will continue to move through the array like this until an entire pass is made without any swaps occurring.
The bubble is sort is basically Quadratic Time: O(n²) when it comes to performance.
class BubbleSort:
def __init__(self, arr):
self.arr = arr;
def bubbleSort(self):
count = 0;
lastIndex = len(self.arr) - 1;
while(count < lastIndex):
if(self.arr[count] > self.arr[count + 1]):
self.swap(count)
count = count + 1;
if(count == lastIndex):
count = 0;
lastIndex = lastIndex - 1;
def swap(self, count):
temp = self.arr[count];
self.arr[count] = self.arr[count + 1];
self.arr[count + 1] = temp;
arr = [9, 1, 5, 3, 8, 2]
p1 = BubbleSort(arr)
print(p1.bubbleSort())
def bubblesort(L,s):
if s >-1 :
bubblesort(L,s-1)
for i in range(len(L)-1-s):
if L[i]>L[i+1]:
temp = L[i+1]
L[i+1] = L[i]
L[i] = temp
return L
Nlist = [3,50,7,1,8,11,9,0,-1,5]
print(bubblesort(Nlist,len(Nlist)))
Answers provided by the-fury and Martin Cote fixed the problem of the infinite loop, but my code would still not work correctly (for a larger list, it would not sort correctly.). I ended up ditching the unsorted variable and used a counter instead.
def bubble(badList):
length = len(badList) - 1
n = 0
while n < len(badList):
for element in range(0,length):
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
n = 0
else:
n += 1
return badList
if __name__ == '__main__':
mylist = [90, 10, 2, 76, 17, 66, 57, 23, 57, 99]
print bubble(mylist)
If anyone could provide any pointers on how to improve my code in the comments, it would be much appreciated.
Try this
a = int(input("Enter Limit"))
val = []
for z in range(0,a):
b = int(input("Enter Number in List"))
val.append(b)
for y in range(0,len(val)):
for x in range(0,len(val)-1):
if val[x]>val[x+1]:
t = val[x]
val[x] = val[x+1]
val[x+1] = t
print(val)
idk if this might help you after 9 years...
its a simple bubble sort program
l=[1,6,3,7,5,9,8,2,4,10]
for i in range(1,len(l)):
for j in range (i+1,len(l)):
if l[i]>l[j]:
l[i],l[j]=l[j],l[i]
def merge_bubble(arr):
k = len(arr)
while k>2:
for i in range(0,k-1):
for j in range(0,k-1):
if arr[j] > arr[j+1]:
arr[j],arr[j+1] = arr[j+1],arr[j]
return arr
break
else:
if arr[0] > arr[1]:
arr[0],arr[1] = arr[1],arr[0]
return arr
def bubble_sort(l):
for i in range(len(l) -1):
for j in range(len(l)-i-1):
if l[j] > l[j+1]:
l[j],l[j+1] = l[j+1], l[j]
return l
def bubble_sorted(arr:list):
while True:
for i in range(0,len(arr)-1):
count = 0
if arr[i] > arr[i+1]:
count += 1
arr[i], arr[i+1] = arr[i+1], arr[i]
if count == 0:
break
return arr
arr = [30,20,80,40,50,10,60,70,90]
print(bubble_sorted(arr))
#[20, 30, 40, 50, 10, 60, 70, 80, 90]
def bubbleSort(a):
def swap(x, y):
temp = a[x]
a[x] = a[y]
a[y] = temp
#outer loop
for j in range(len(a)):
#slicing to the center, inner loop, python style
for i in range(j, len(a) - j):
#find the min index and swap
if a[i] < a[j]:
swap(j, i)
#find the max index and swap
if a[i] > a[len(a) - j - 1]:
swap(len(a) - j - 1, i)
return a
I'm trying to find the most pythonic way to find out if numbers in a list are sequential. To give some background, I have a list of numbers gathered that exist in a folder, and I need to find out which numbers are missing.
I gather all of the numbers, and then make another list from the range(beginning, end+1) of what numbers should be there. I very easily made something to show me all of the numbers missing:
missing = [x for x in existingNumbers if x not in shouldBeNumbers]
The problem is that if I print out all of those, there are a lot of numbers that could be condensed (i.e. 1, 2, 3, 4, 7, 10 could be printed as 1-4, 7, 10) because there could be massive amounts of numbers missing.
I've tried two approaches:
For both ways, frameRange is range(startFrame, endFrame+1) and frameList is a list generated from what exists currently.
1)
for x in frameRange:
if x not in frameList:
if originalFrame == None:
originalFrame = x
elif originalFrame:
if lastFrame == None:
lastFrame = x
elif lastFrame:
if lastFrame == x-1:
lastFrame = x
else:
if originalFrame != lastFrame:
missingFrames.append(str(originalFrame)+"-"+str(lastFrame))
originalFrame = x
lastFrame = x
else:
missingFrames.append(str(originalFrame))
originalFrame = x
lastFrame = x
if x == endFrame:
if originalFrame != lastFrame:
missingFrames.append(str(originalFrame)+"-"+str(lastFrame))
originalFrame = x
lastFrame = x
else:
missingFrames.append(str(originalFrame))
originalFrame = x
lastFrame = x
2)
i = 0
while i < len(frameRange):
if frameRange[i] in frameList:
i += 1
else:
if i + 1 < len(frameRange):
if frameRange[i + 1] in frameList:
missingFrames.append(str(frameRange[i]))
i += 1
else:
j = 1
while frameRange[i+j] not in frameList:
aheadFrameNumber = int(str(j))
if i + j + 1 < len(frameRange):
j += 1
else:
break
missingFrames.append(str(frameRange[i])+"-"+str(frameRange[aheadFrameNumber]))
if i + aheadFrameNumber + 1 < len(frameRange):
i += aheadFrameNumber + 1
else:
missingFrames.append(str(frameRange[i]))
The first way was working, but since it happens on the current frame checking the last, whenever the last frame was gone it wouldn't append the last missing section to the list. For the second way I had to keep wrapping everything in if statements because I kept getting index exceptions when moving forwards.
I think I have to step back, re-think, and approach it differently. I'm wondering if there is a much better way to do this in python that I haven't thought about yet because I don't know the function. Both ways started to get a little out of hand.
Try something like this
missing=[]
numbers.insert(0, 0) # add the minimum value on begining of the list
numbers.append(41) # add the maximum value at the end of the list
for rank in xrange(0, len(numbers)-1):
if numbers[rank+1] - numbers[rank] > 2:
missing.append("%s-%s"%(numbers[rank] +1 , numbers[rank+1] - 1))
elif numbers[rank+1] - numbers[rank] == 2:
missing.append(str(numbers[rank]+1))
print missing
which for numbers = [1,4,6,10, 12,] and numbers should be present are from 1 to 40 you will have :
['2-3', '5', '7-9', '11', '13-40']
def find_missing_range(my_numbers, range_min, range_max):
expected_range = set(range(range_min, range_max + 1))
return expected_range - set(my_numbers)
def numbers_as_ranges(numbers):
ranges = []
for number in numbers:
if ranges and number == (ranges[-1][-1] + 1):
ranges[-1] = (ranges[-1][0], number)
else:
ranges.append((number, number))
return ranges
def format_ranges(ranges):
range_iter = (("%d" % r[0] if r[0] == r[1] else "%d-%d" % r) for r in ranges)
return "(" + ", ".join(range_iter) + ")"
def main(my_numbers, range_min, range_max):
numbers_missing = find_missing_range(my_numbers, range_min, range_max)
ranges = numbers_as_ranges(numbers_missing)
return format_ranges(ranges)
if __name__ == '__main__':
range_min, range_max = 1, 40
print main([1, 4, 6, 10, 12], range_min, range_max)
print main([1, 2, 3, 4, 10, 20], range_min, range_max)
(2-3, 5, 7-9, 11, 13-40)
(5-9, 11-19, 21-40)