Related
I've a function which aim is to find numbers that you cannot pair with others. If a number cannot be paired up with another identical number, then you will have to return it.
example:
[1,1,1,1, 2, 3, 4]
expected result:
[2,3,4]
def pair(input):
while len(input) > 2:
for i in range(len(input) - 1):
for j in range(len(input) - 1):
print(input)
if input[i] == input[j]:
input.pop(i)
input.pop(j)
print(input)
else:
break
return input
print(pair([1,1,1,1, 2, 3, 4]))
If you can use a library, you could use a Counter from collections, and just return the values in the list that have an odd count (since that implies there is one of those numbers that cannot be paired with another):
from collections import Counter
ll = [ 1, 2, 1, 3, 2, 3, 1, 4, 1, 2, 3, 4 ]
c = Counter(ll)
[num for num, cnt in c.items() if cnt % 2 == 1]
Output:
[2, 3]
One way to solve this problem is to find the unique elements in the list, and if an element occurs an odd number of times the in the list, returned it.
def pair(lst):
set_lst = set(lst)
output = []
for elem in set_lst:
if lst.count(elem) % 2 != 0:
output.append(elem)
return output
print(pair([1, 1, 1, 1, 2, 3, 4]))
Keeping track of the numbers that occurred an odd number of times:
def pair(lst):
odd = set()
for x in lst:
odd ^= {x}
return list(odd)
print(pair([1,1,1,1, 2, 3, 4]))
According your example input list is sorted. In this case #KetZoomer's solution is not effective, because it searching for the elem in whole list and counting it every time (lst.count(elem))
If you counted number of 1's you don't need to search for 2 in whole list from 0th element to last element again.
You should to use something like this:
def pairs(lst: list) -> list:
if len(lst) > 0:
# set first element
current_el = lst[0]
duplicate_count = 1
values_without_pair = []
else:
return []
# loop for elements starting from 2nd
for i in range(1, len(lst)):
# if looped element same as stored in memory increase count and go to next element
if current_el == lst[i]:
duplicate_count += 1
# if element is changed then check count value is even or not
# and set new element for checking
else:
if duplicate_count % 2 != 0:
values_without_pair.append(current_el)
duplicate_count = 1
current_el = lst[i]
# process last element
if duplicate_count % 2 != 0:
values_without_pair.append(current_el)
return values_without_pair
print(pairs([1,1,1,1,2,3,4]))
Hello there i'm trying sum_consecutives as the function name mention in array example:
[1,1,7,7,3] should return [2,14,3]
Problem:
Looks like my algorithm not working with all the array i get this result everytime [2,14]
the function:
def sum_consecutives(s):
sum = 0
X = []
for i in range(0,len(s)-1):
print( i)
if s[i] == s[i+1]:
sum += s[i]
else:
X.append(sum+s[i])
sum = 0
return X
Your algorithm won't work because you're iterating from index 0 until index len(s) - 1, excluding the last element since the range function is end-exclusive (range(0, 5) iterates from 0 to 4). You can iterate over all elements and introduce a new variable to store the last element:
def sum_consecutives(values):
result = []
# Stores the first consecutive element
last_elem = None
for curr_elem in values:
# If the last element is not initialized,
# initializes it and proceed with the iteration
if last_elem is None:
last_elem = curr_elem
continue
# If the current element is equal to the last
# element, push the sum to the result list
if last_elem == curr_elem:
result.append(last_elem + curr_elem)
# Otherwise, push both elements to the result list
else:
result.append(last_elem)
result.append(curr_elem)
# Reset the last element set
last_elem = None
# If there's an element not paired (i.e. not None),
# push its value to the result array
if last_elem is not None:
result.append(last_elem)
return result
Some tests:
assert sum_consecutives([1, 1, 7, 7, 3]) == [2, 14, 3]
assert sum_consecutives([1]) == [1]
assert sum_consecutives([1, 1]) == [2]
assert sum_consecutives([1, 2, 1]) == [1, 2, 1]
Also, avoid naming your variable sum, it'll shadow the sum built-in.
I made a program to take elements from a list and a tuple simultaneously {ie. one from list then from tuple and then back from list and so on} and placing them in a new list and sorting them while inserting using insertion sort. The problem I am facing is the numbers are not sorting properly.
the output I'm getting [8, 6, 9, 4, 3, 1, 2, 5, 7]
the output I want. [1,2,3,4,5,6,7,8,9]
list = [8,6,4,2]
tuple = (9,5,7,1,3)
final = [list[0],] # creating a final list with the value list[0]
list.pop(0) # removing the first element from list
l = len(list)
t = len(tuple)
# now comparing whoes length is greater and assigning it to j
if l > t:
j = l
else:
j = t
b = 0 # variable to keep the count of elements in the final list starting from 0 to n-1
for i in range(j):
n = b
if i < l: # Making sure the index dosen't exceed the list
temp = list[i]
final.append(temp) # appending the value to last
while temp < final[n] & n>-1:
final[n+1] = final[n]
n = n-1
final[n+1] = temp
b+=1 # a value is added to final list so the total no of elements increases
n=b
if i < t: # Making sure the index dosen't exceed the tuple
temp = tuple[i]
final.append(temp)
while temp < final[n] & n>-1:
final[n+1] = final[n]
n = n-1
final[n+1] = temp
b+=1
print(final)
You can just use the .sort() method to get the correct order.
...
b+=1
final.sort()
print(final)
def second_highest(list):
""" (list of int) -> int
How do you find the second highest value from the list of integers without using remove, pop, or sort (which I tried) since I need to use the same list later on?
There will be no duplication of numbers.
list.sort()
return list[-2]
I tried removing the highest number using max, sorting the list, but since those mutates the list, I can't use them.
Use the builtin sorted oy mylist, which will not modify mylist(thanks to #Tofystedeth)
mylist = [1, 2, 8, 3, 12]
print(sorted(mylist, reverse=True)[1])
data = [1,2,8,3,12]
largest = None
second_largest = None
for a in data:
if not largest or a > largest:
if largest:
second_largest = largest
largest = a
print("largest: {}".format(largest))
print("second_largest: {}".format(second_largest))
arr = [2, 3, 4, 2, 4, -3, 43, -4, -25, 45, 9]
my_list = list(set(arr))
my_list.sort()
if len(my_list) == 1:
print(my_list[0])
elif len(my_list) >= 2:
print(my_list[-2])
nums=[1,2,3,3,5,4,5,5,2]
#making new set to maintain uniqueness
new_list= set(nums)
high= max(nums)
new_list.remove(high)
print(max(new_list))
#This code uses remove but does not do any changes to the given list
print(nums)
##This will work even if numbers are negative. Logic is : convert the list() to set() and back to list to use the sort() method and then print the -2 position value in the list. This gives you the second-highest value.## "Python 3"
if __name__ == '__main__':
n = int(input())
arr = list(map(int, input().split()))
z = list(set(arr))
z.sort()
print(z[-2])
array = [2, 3, 4, 2, 4, -3, 43, -4, -25, 45, 9]
arr = array.copy()
z = max(arr)
# if list contains duplicate max elements removing them until We get Second highest
while max(arr) == z:
arr.remove(max(arr))
print(max(arr))
print(array)
Here is the code to find the 2nd largest number in the list without using any inbuilt functions.
data = [11,22,1,2,5,67,21,32]
max1 = data[0] # largest num
max2 = data[1] # second largest num
for num in data:
if num > max1:
max2 = max1 # Now this number would be second largest
max1 = num # This num is largest number in list now.
# Check with second largest
elif num > max2:
max2 = num # Now this would be second largest.
print(max2)
I think my answer is more simple and more readable for beginners
x=[2,3,4,2,5,9,8,4,5,6,7,8,9,2,1,3,4,5]
max=-10000000
for i in x:
if(i>max):
secondmax=max
max=i
elif(i>secondmax and i!=max):
secondmax=i
print(secondmax)
Here is a way to do it using sort. However, it gives you the possibility to reuse the list since you are temporarily storing the list arr in sortedArr. Calling arr by itself would return the original list. Here you can Try it online!
# Finding a runner up number in a List of Arrays
# Second highest number in a list
arr = [2,3,6,6,5]
sortedArr = sorted(arr,reverse=True) # Sorting the array in descending order.
highest = sortedArr[0] # Assign the highest value in the array to the variable `highest`.
secondHighest = 0 # Initializing the variable `secondHighest` to 0.
for x in (sortedArr): # Iterating through the sorted array and checking if the value is equal to the highest value.
if(x == highest):
continue # If it is, it will continue to the next value.
else:
secondHighest = x # If it is not, it will assign the value to the variable `secondHighest`
break # break out of the loop.
print(secondHighest) # Printing the value of the variable `secondHighest`.
>>> 5
list = [2,3,5,1,7,8]
secondhighest = max([i for i in list if i<max(a)])
This will give you the second highest value in the list.
Copy unique list elements to another list (if Already the list elements are unique, go to step 2) .
You should find the maximum in the list and save its index. Then remove it from the list using the remove() function and then find the maximum of the new list (with the original maximum value removed) and that will be your second highest element. You can then use the insert() method to add back the original maximum back into the list.
Here is the code to find the maximum and second maximum number in a list or array(python). Tried with all the combination of elements(negative and positive), it is working fine. We can optimize this code as i am not using any inbuilt method.
Below is the list combinations this code is tested with:
la = [1,1,1,1,1],la = [1,1,1,1,1,0],la = [5,4,1,2,3],la = [3,6,2,7],la = [1,2,3,4,5],la = [4,5,1,2,3],la = [5,5,4,3,2,1],la = [-1,1,0,0,0],la = [-1,-2,-3,-4], la = [-1,0],la = [-2,-2,-2,-2,0,1,1,1,1]
def findSecmax(la):
mx = la[0]
sec = 0 # or sec = min(la) or we can take (- sys.maxsize)
for i in la:
if i < sec:
sec = i
for i in la:
if i > mx:
mx = i
for i in la:
if i > sec and mx > i:
sec = i
if sec == mx:
return "we have same elements in the list. So max is {}".format(mx)
else:
return mx,sec
print(findSecmax(la))
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