The highest even number in a list - python

I want to find the highest even number in a list. The code I have used is able to do so successfully, but I don't know why my code is running right.
Please find my code below:
def highest_even(*list):
for numbers in list:
if numbers % 2 == 0:
c= numbers
print(c)
highest_even(1,2,3,4,5,6,7,8,9,10,11,12,111,222,444,555)
Even though I have only validated the even numbers, the output I am having is only the highest even number. Why is it so? Please help

Your list is ordered and you replace the value of c by the last value you evaluated as even. So at the end you get the highest number, try to shuffle your list using shuffle() and you will not get the right result.
Here's how you can fix your function :
def highest_even(*list):
c = 0
for numbers in list:
if numbers % 2 == 0:
if numbers > c:
c= numbers
print(c)
highest_even(1,2,3,4,5,6,7,8,9,10,11,12,111,222,444,555)

You can also create a list of evens, sort it, and take first value from the right:
def maxeven(list):
return sorted([x for x in list if x % 2 == 0])[-1]

I would do this instead: -
def highest_even(list):
evens = []
for i in list:
if i % 2 == 0:
evens.append(i)
return max(evens)
print(highest_even([1,2,3,4,5,6,7,8,9,10,11,12,111,222,444,555]))

Try to include print(c) inside the for() loop like so:
for numbers in list:
if numbers % 2 == 0:
c = numbers
print(c)
You get only the highest even number, because after the loop is done, you print only the last element.

You can obtain the Highest Even value From your mentioned tuple not list by using filter() and lambda Expression.
Highest Even Element in The Tuple
Code Syntax
def highest_even(*tuple):
lis = filter(lambda x: x % 2 == 0, tuple)
return print(f"your maximum even number is: {max(lis)}")
highest_even(1,2,3,4,5,6,7,8,9,10,11,12,111,222,444,555)
Output
your maximum even number is: 444
[Program finished]
Sorting Depending on Highest Even Element
Code Syntax
def highest_even_list(*tuple):
lis = sorted(filter(lambda x: x % 2 == 0, tuple), reverse=True)
return print(f"Sorted List depending on The highest Even Elements:\n{lis}")
highest_even_list(1,2,3,4,5,6,7,8,9,10,11,12,111,222,444,555)
Output
Sorted List depending on The highest Even Elements:
[444, 222, 12, 10, 8, 6, 4, 2]
[Program finished]
Using Kwargs for Reversing
You can also decide if you want to sort it ascending or descending using **kwargs
Code Syntax
def highest_even_list(*tuple, **kwargs):
lis = sorted(filter(lambda x: x % 2 == 0, tuple), **kwargs)
return print(f"Sorted List depending on The highest Even Elements:\n{lis}")
highest_even_list(1,2,3,4,5,6,7,8,9,10,11,12,111,222,444,555, reverse=True)
Output
Sorted List depending on The highest Even Elements:
[444, 222, 12, 10, 8, 6, 4, 2]
[Program finished]

Related

How to append to a list two numbers from within the list that add up to a number in the list?

First, I want to find the highest number in the list which is the second number in the list, then split it in two parts. The first part contains the 2nd highest number, while the second part contains the number from the list that sums to the highest number. Then, return the list
eg: input: [4,9,6,3,2], expected output:[4,6,3,6,3,2] 6+3 sums to 9 which is the highest number in the list
Please code it without itertools.
python
def length(s):
val=max(s)
s.remove(val)
for j in s:
if j + j == val:
s.append(j)
s.append(j)
return s
Here's what I have but it doesn't return what the description states.
Any help would be appreciated as I spent DAYS on this.
Thanks,
The main issue in your code seems to be that you are editing the list s whilst iterating through it, which can cause issues with the compiler and is generally just something you want to avoid doing in programming. A solution to this could be iterating through a copy of the original list.
The second problem is that your program doesn't actually find the second biggest value in the list, just a value which doubles to give you the biggest value.
The final problem (which I unfortunately only noticed after uploading what I thought was a solution) is that the split values are appended to the end of the list rather than to the position where originally the largest value was.
Hopefully this helps:
def length(array):
val = max(array)
idx = array.index(val) # gets the position of the highest value in the array (val)
array.remove(val)
for i in array.copy(): # creates a copy of the original list which we can iterate through without causing buggy behaviour
if max(array) + i == val:
array = array[:idx] + [max(array), i] + array[idx:]
# Redefines the list by placing inside of it: all values in the list upto the previous highest values, the 2 values we got from splitting the highest value, and all values which previously went after the highest value.
return array
This will return None if there is no value which can be added to the second highest value to get the highest value in the given array.
Input:
print(length([1,2,3,4,5]))
print(length([4,8,4,3,2]))
print(length([11,17,3,2,20]))
print(length([11,17,3,2,21]))
Output:
[1, 2, 3, 4, 4, 1]
[4, 4, 4, 4, 3, 2]
[11, 17, 3, 2, 17, 3]
None
Here are the docs on list slicing (which are impossible to understand) and a handy tutorial.
when you say "The first part contains the 2nd highest number" does that mean second highest number from the list or the larger of the two numbers that add up the largest number from list?
Here I assume you just wanted the larger of the two numbers that add up to the largest number to come first.
def length(s:list):
#start by finding the largest value and it's position in the list:
largest_pos = 0
for i in range(len(s)):
if s[i] > s[largest_pos]:
largest_pos = i
# find two numbers that add up to the largest number in the s
for trail in range(len(s)):
for lead in range(trail, len(s)):
if (s[trail] + s[lead]) == s[largest_pos]:
if s[trail] > s[lead]:
s[largest_pos] = s[trail]
s.insert(largest_pos +1, s[lead])
else:
s[largest_pos] = s[lead]
s.insert(largest_pos + 1, s[trail])
return s
# if no two numbers add up to the largest number. return s
return s
Since you are limited to 2 numbers, a simple nested loop works.
def length(s):
val = max(s)
idx = s.index(val)
s.remove(val)
for i in range(len(s) - 1):
for j in range(i + 1, len(s)):
if s[i] + s[j] == val:
s = s[:idx] + [s[i], s[j]] + s[idx:]
return s
print(length([4,9,6,3,2]))
Output:
[4, 6, 3, 6, 3, 2]
I used deque library
first to find the highest element or elements then remove all of them and replace them with second high value and rest like : 9 replace with 6 and 3 in example:
from collections import deque
l = [4, 9, 6, 3, 2]
a = deque(l)
e = a.copy()
s = max(a)
while s in a:
a.remove(s) # remove all highest elements
s2 = max(a) # find second high value
c = s - s2
for i in l:
if i == s:
w = e.index(i) # find index of high values
e.remove(max(e))
e.insert(w, s2)
e.insert(w+1, c)
print(list(e))

Finding the only odd number or the only even number in a list

I am looking at this challenge:
You are given an array (which will have a length of at least 3, but could be very large) containing integers. The array is either entirely comprised of odd integers or entirely comprised of even integers except for a single integer N. Write a method that takes the array as an argument and returns this "outlier" N.
Here is my attempt:
def find_outlier(i):
p=0
im=0
if i[0]%2==0 :
p=p+1
else :
im=im+1
if i[0]%2==0 :
p=p+1
else :
im=im+1
if i[0]%2==0 :
p=p+1
else :
im=im+1
if p<im :
for e in i :
if e%2 ==0:
return print(e)
else:
for e in i :
if e%2 !=0 :
return print(e)
find_outlier([160, 3, 1719, 19, 11, 13, -21])
It returns 3 when it should clearly return 160.
What am I missing?
Your three if statements are all identical. They're all looking at the first element. You want i[1] in the second and i[2] in the third. That solves the problem.
As others have said, the repeated statements will append your p and im and not give you the values you expect from them.
There are many ways to approach this task, but this could be a good beginner-friendly approach to reference:
def find_outlier(array):
evens = [] # this will be filled with the evens numbers
odds = []. # this will be filled with the odds numbers
for val in array:
if val % 2 == 0: # if even, add to evens
evens.append(val)
else: # If not even (i.e. odd) add to odds
odds.append(val)
if len(evens_index) == 1: # outlier will have a list length 1
return evens[0]
elif len(odds_index) == 1:
return odds[0]
else:
return None.
Two issues:
The code looks three times at the first element of the list, while you should look at three different elements
The return statements return the value that the print function returns, which is None. You move the printing outside of the function, as the function should just return the number, not print it.
So if we only correct these two issues we get:
def find_outlier(i):
p=0
im=0
if i[0]%2==0 :
p=p+1
else :
im=im+1
if i[1]%2==0 : # element at 1
p=p+1
else :
im=im+1
if i[2]%2==0 : # element at 2
p=p+1
else :
im=im+1
if p<im :
for e in i :
if e%2 ==0:
return e # return the value, not `print()`
else:
for e in i :
if e%2 !=0 :
return e
print(find_outlier([160, 3, 1719, 19, 11, 13, -21]))
Now you can also avoid code repetition:
The variables p and im will always add up to 3, so one of those can be left out. You have all the info you need when you just track the value of im only.
The three if blocks are essentially the same, so a loop that iterates 3 times is more appropriate. You can even use sum().
The final if..else blocks also look very similar. You can instead determine what e%2 should be equal to (with a variable) and just keep one block. Also this can be done with a shorter expression, using next().
I would also suggest using more descriptive variable names:
def find_outlier(lst):
odds = sum(value%2 for value in lst[:3])
target = int(odds < 2)
return next(value for value in lst if value%2==target)
print(find_outlier([160, 3, 1719, 19, 11, 13, -21]))
If you are looking for an outlier you want to check i[0] i[1] and i[2]. You are checking i[0] 3 times.
Since p is 3 and im is 0, it thinks it's looking for the first odd number it comes across, which is 3.

Count the unique elements in a list without set

I am currently attempting to make a program that will count and print the number of unique elements in a list.
My code:
def solution(N, A):
yee = 1
for i in range(1, len(A)):
j = 0
for j in range(i):
if(A[i] == A[j]):
yee-=1
if(i==j+1):
yee +=1
print(yee)
N = int(input())
A = []
n = 0
for e in input().split():
if(n<N):
A.append(int(e))
n+=1
solution(N, A)
With the list containing (1 2 3 1 4 2 5 6 7 8) the output is supposed to be 6. However, my program is returning 8. I believe this is due to the program counting the 1 and 2, even though they are not technically unique in the problem. I'm sure it's and easy fix, but I just can't seem to figure it out. Any help would be greatly appreciated!!
The only way you would get the output of 6 for (1, 2, 3, 1, 4, 2, 5, 6, 7, 8) would be if you wanted to count the number of elements that appear exactly once, as opposed to the number of unique elements (there are 8 elements, of which two are repeated more than once).
You could do this in a one-liner:
def num_single_elements(A):
return len(list(e for e in A if A.count(e) == 1))
Similarly if you need to keep check of the number of elements further on in your code, I like dictionary comprehension for this kind of problem:
dict_A = {x:A.count(x) for x in A}
print(len([x for x in dict_A if dict_A[x] == 1]))
As Green Cloak Guy said, you seem to be looking for the number of elements which appear exactly once, and his answer contains a solution to that. Here's a simple solution for finding the number of unique elements:
def unique_elements(A):
return len([ 1 for (index, a) in enumerate(A) if A.index(a) == index ])
The idea here is to count up the first occurrence of each unique value.
enumerate allows us to get the index of the item, as well as the item itself, as we iterate;
A.index(a) gives the index of the first time the value of a appears in A.
So, if we count up all the times index equals A.index(a), we're counting the first time an item appears which has never appeared before, which is equal to the number of unique elements.

Python Magic number guesser

I am trying to remove numbers from a list until there is only one item left. I am having trouble with my for loop. It keeps giving the error stating:
File "C:/Users/kramsey/Desktop/Python/NumberGuesser2.py", line 28, in <module>
list.remove(B)
ValueError: list.remove(x): x not in list
Code:
B = random.choice(list)
if ready == "ok":
lessthan = input("is your number less than {}".format(B)).strip().lower()
if lessthan == "yes":
for numbers in list:
B = int(B+1)
list.remove(B)
print(list)
I want it to delete the numbers that are not less than the random.choice(list) without printing an error to the user once it hits an integer that isn't in the list.
It always tells the user that list.remove(x) not in list and doesn't continue through my for loop.
Let us simplify your problem to having a list (appropriately named l):
l = [1, 3, 4, 6, 7, 9]
and a random number (for simplicity's sake, we we'll just set this to 5):
B = 5
Now, we can't iterate over l and remove items from l as this will lead us into problems (as you have seen with that error). So the best way to do this is re-define l as a new list that is made with a list-comprehension.
l = [i for i in l if i > B]
and that will leave l as:
[6, 7, 9]
This is the right way to do what you want and hopefully you can incorporate this into your code.
Assuming your list is consisted of sorted numbers, you would have to do something like that:
if lessthan == 'yes':
index = len(list) - 1
while list[index] >= B:
list.remove(list[index])
index -= 1
print(list)
Bear in mind, that you if you are going to alter the list you are iterating over by removing/deleting elements, you should iter backwards(from the end of list to the beginning). Otherwise, you could skip over some elements by deleting an element in the middle of the list.

Python | The median is the middle number in a sorted sequence of numbers

def median (lst):
lst.sort()
if len(lst) % 2==0:
print sum(lst[len(lst)-1:len(lst)])
else:
print sum(len(lst)/2)
median([4, 5, 5, 4,2,5,6,9,10])
The error occurs at: print sum(len(lst)/2)
TypeError: 'int' object is not iterable
why doesn't it work?
You need to replace print sum(len(lst)/2) with:
print lst[len(lst) / 2]
because what you want is to take the middle element of the list. What was wrong was to sum not on a list of numbers but on a number. What you could do if you wanted to use the sum notation is the following:
print sum([lst[len(lst)//2]])
meaning to include the number in a list.
Why not use the built-in function?
>>> from statistics import median
>>> median([1, 3, 5])
above taken from this post: Median code explanation
or, if you must do it the hard way:
def median(a):
ordered = sorted(a)
length = len(a)
return float((ordered[length/2] + ordered[-(length+1)/2]))/2
Also taken from the same post...

Categories

Resources