def my_max():
#using input to collect number to list
list_a = input("print your list with numbers: ").split(",")
# Searching for the highest number
max = 0
for i in list_a:
if i > str(max):
max = i
print(max)
my_max()
When i write numbers to input, sometimes the highest number is being printed, but not always.
For an example, if i write :"54,64,446 "
the number "64 is being printed. Do anybody knows why?
You need to map it into list of ints before you do the logic:
def my_max():
# using input to collect number to list
list_a = input("print your list with numbers: ").split(",")
# Searching for the highest number
return max(map(int, list_a))
print(my_max())
Sample run:
print your list with numbers: 54,64,446
446
Splitting on ',' gives you a list of strings. What you observed is an expected behaviour because you find max of a list of strings in contrast to list of integers.
Without using a max(), I would go something like this:
def my_max():
# using input to collect number to list
list_a = list(map(int, input("print your list with numbers: ").split(",")))
# Searching for the highest number
max = list_a[0]
for x in list_a[1:]:
if x > max:
max = x
return max
print(my_max())
Your list_a contains strings, not numbers. When you do your comparison, you are comparing the values of these strings. The result of this is the highest value alphabetically, rather than numerically.
Taken as strings rather than numbers, 64 > 54 > 446
Related
I need a help. I want to chunk my list with float numbers into sublists to compare two decimal numbers to see if the difference between the consecutive numbers are in the range 10. To more specific, my expectation is to split them for example, those numbers from 70-80 to be in a list, from 80-90 to be in another list, and so on.
Firstly, I sorted my list and then tried to compare two elements, but the result is different from that I want.
Here is my attempt to compare numbers:
mylist = [125.90720268, 122.08697428, 86.70855817, 82.68482956, 75.99304643, 71.92440719, 80.92440719]
chunked_list = []
sort_list = sorted(mylist, key = lambda x:float(x))
curr = [sort_list[0]]
print("sort_list = ", sort_list)
for x in sort_list[1:]:
if abs(x - curr[-1]) < 10:
chunked_list.append(curr)
curr = [x]
else:
curr.append(x)
chunked_list.append(curr) ```
The result is:
[[71.92440719],
[75.99304643],
[80.92440719],
[82.68482956],
[86.70855817, 122.08697428],
[125.90720268]]
while I want to have this result:
[[71.92440719, 75.99304643], [80.92440719, 82.68482956, 86.70855817], [122.08697428, 125.90720268]]
Also, I tried to use math.isclose() function to compare two decimal numbers, but I failed again. I really appreciate that someone tells me where I make a mistake.
You can use itertools.pairwise (or its equivalent recipe if you're using Python of version < 3.10) to iterate through the list in adjacent pairs, and append to the output list a new sub-list if the difference between the pair is greater than 10 while keep appending to the last sub-list the current item:
from itertools import pairwise
output = []
for a, b in pairwise(sorted(mylist)):
if not output or b - a > 10:
output.append([] if output else [a])
output[-1].append(b)
Given your sample input, output becomes:
[[71.92440719, 75.99304643, 80.92440719, 82.68482956, 86.70855817], [122.08697428, 125.90720268]]
Demo: https://replit.com/#blhsing/ImperturbableCrushingAdministrator
EDIT: Since you updated your question with a revised requirement that the numbers should be grouped in multiples of 10, you can append a new sub-list to the output list when the current item divided by 10 is different from the first item of the last sub-list divided by 10:
output = []
for i in sorted(mylist):
if not output or i // 10 != output[-1][0] // 10:
output.append([])
output[-1].append(i)
output becomes:
[[71.92440719, 75.99304643], [80.92440719, 82.68482956, 86.70855817], [122.08697428, 125.90720268]]
Demo: https://replit.com/#blhsing/ElaborateUsedRotation
I want to find if the Input String has Odd Product for distinct numbers:
I did this so far:
# To get input string into list of integer
input = [int(i) for i in input.split()]
# to get odd numbers
sequence=filter(lambda i: i % 2, sequence)
I want to use an operation where I can filter distinct odd numbers in a list and multiply until I get odd number and return true if the result is not odd return false.
I am new to lamda and filter.
I want to know how can I do using this in one statement in Python
You can use itertools.accumulate to repeatedly apply a function (e.g. multiplication) to an iterable:
>>> from itertools import accumulate
>>> bool(list(accumulate({int(i) for i in input().split() if int(i) % 2}, int.__mul__))[-1] % 2)
1 2 3 4 5
True
For filtering distinct odd numbers in a list you can use list comprehension along with set(set is used to get distinct values).
input = [int(i) for i in input().split()]
input = list(set([i for i in input if i%2!=0])) # it would give distinct odd values
I manage to solve the 4th problem of Project Euler & want to take it a step further by not only finding the answer but assigning the corresponding multiplying 3-digits to the answer too. I basically want to assign the corresponding multiples to the palindrome i.e. {palindrome: digit1 digit2}. that is digit1*digit2=palindrome.
For those of you who have not done the Project Euler, here is the question:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99. Find the largest palindrome made from the product of two 3-digit numbers.
ns = str(n)
ns_list = []
ns_list_to_int = []
#outside for loop with first 3-digit 'num' and inside loop with second 3-digit 'i'
for num in range (100,1000):
for i in range(100,1000):
n = i*num
#need to convert to string & check if reverse of string == string, if so append to list
ns = str(n)
if ns[::-1] == ns:
ns_list.append({ns:str(i) + ' 'str(num) })
#recreate new list with integers to sort
for i in ns_list:
ns_list_to_int.append(int(i))
#sort in descending order and call the first number
ns_list_to_int = sorted(stuffs, key=int, reverse=True)
ns_list_to_int[0]
tried to get it with ns_list.append({ns:str(i) + ' 'str(num) }) but it doesn't seem to work. Also, not sure how then I would be able to sort it if it is a dictionary.
Instead of appending just the product (your variable ns), you could append a tuple/list/object which contains not only the palindromic number but also the two multiples.
Then all you need to change further down is the sorting function.
Quick and dirty example:
ns_list = []
ns_list_to_int = []
#outside for loop with first 3-digit 'num' and inside loop with second 3-digit 'i'
for num in range (100,1000):
for i in range(100,1000):
n = i*num
#need to convert to string & check if reverse of string == string, if so append to list
ns = str(n)
if ns[::-1] == ns:
pint = int(ns) # convert palindrome to int
t = (i,num,pint) # all the info you need for later
ns_list.append(t)
#sort in descending order and call the first number
ns_list_to_int = sorted(ns_list, key=lambda x:x[2], reverse=True) # sorting by the palindrome
ns_list_to_int[0]
Simple approach is to replace ns_list with a dict, then replace ns_list.append(ns) with ns_dict[num, i] = ns.
Alternatively, to keep the palindromes as the top level iterable component, you can store all the pairs that produced a particular palindrome in a list, using collections.defaultdict(list) to simplify the code:
from collections import defaultdict
ns_dict = defaultdict(list)
#outside for loop with first 3-digit 'num' and inside loop with second 3-digit 'i'
for num in range(100,1000):
for i in range(100,1000):
n = i*num
ns = str(n)
if ns[::-1] == ns:
ns_dict[ns].append((num, i))
Now when you iterate ns_dict, you can see all the pairs you checked that produced that palindrome:
ns_list_with_factors = sorted(ns_dict.items(), key=lambda x: int(x[0]), reverse=True)
print(ns_list_with_factors[0]) # Displays both number and the pairs that produced it
for ns, pairs in ns_dict.items():
...
Let's say i have a list of list containing:
L = [['10.2','9.1','G'],['12.9','7.4','H'],['5.6','4.3','G'],['5.7','4.5','G']]
where the alphabets in each list within the list of list represents something like 'type'
In this case, python will request for the user input of four float numbers separated by ':', for example;
input = 5.5:4.4:5.7:4.7
Before python proceed on dealing with the input, as shown in the list of list, the alphabets in each list at the third section represents a type therefore;
For example, upon user input, python will compare the number of the input to the values in the list of list within the range of the user input of type 'G'.
Hence, python will output the list from the list of list in which the numbers are in range as the user input. So,
input = 5.5:4.4:5.7:4.6
output = [5.6,4.3] and [5.7,4.5]
note: the input consist of four float numbers separated by ':' and we can assume the first half is a set 5.5:4.4 and the second half is a set 5.7:4.6.
I gave it a try but i don't know how i would be able to output the list within range to the input.
L = [['10.2','9.1','G'],['12.9','7.4','H'],['5.6','4.3','G'],['5.8','4.5','G']]
userinput = input("Enter floats:") #example 5.5:4.4:5.7:4.6
strSeparate = userinput.split(':')
floatInput = [float(i) for i in strSeparate] #turn input into float
inputList = [floatInput[:2],floatInput[2:]] #[[5.5,4.4],[5.7,4.6]]
for line in L:
for val in inputList:#???
output format would be:
[[5.6,4.3],[5.7,4.5]]
You can do it as shown below.
First the user input is split on the :, the values are converted to floats, and an iterator is created to help pair the values with zip(). Then each pair is compared with the ranges in L. A pair lies within the range if both of its values lie between the upper and lower values of the range. Any pair that lies within the range is added to the results list.
L = [['10.2','9.1','G'],['12.9','7.4','H'],['5.6','4.3','G'],['5.8','4.5','G']]
inputs = [float(s) for s in '5.5:4.4:5.7:4.6'.split(':')]
it = iter(inputs)
results = []
for pair in zip(it, it):
for line in L:
if line[2] == 'G':
upper = float(line[0])
lower = float(line[1])
if ((lower <= pair[0] <= upper) and
(lower <= pair[1] <= upper)):
results.append([upper, lower])
print(results)
This will output:
[[5.6, 4.3], [5.8, 4.5]]
Note that this code will include duplicate values in results if there is more than one input pair that fall within a range. If this is not wanted you can use a set instead of a list for results, and add tuples to the set (because lists are not hashable).
Also this assumes that the upper and lower bounds for each sub list in L is in order (upper then lower). If that's not the case you can do this:
upper = float(line[0])
lower = float(line[1])
lower, upper = lower, upper if lower <= upper else upper, lower
The solution using numpy.arange() and numpy.any() funcions:
import numpy as np
L = [['10.2','9.1','G'],['12.9','7.4','H'],['5.6','4.3','G'],['5.7','4.5','G']]
userinput = "5.5:4.4:5.7:4.6" #example 5.5:4.4:5.7:4.6
floatInput = [float(i) for i in userinput.split(':')] #turn input into float
result = []
for i in (floatInput[0:2], floatInput[2:]):
r = np.arange(i[1], i[0], 0.1) # generating float numbers range
items = [l[0:2] for l in L
if isinstance(np.any([r[r >= float(l[0])], r[r >= float(l[1])]]), np.ndarray)
and l[0:2] not in result]
if (items): result.extend(items)
print(result)
The output:
[['5.6', '4.3'], ['5.7', '4.5']]
I used split to remove whitespaces and turn string into list and using built in function I tried to find the max and min values of the list but I gave incorrect ans also I want ans in formate " x y "where x and y are max and min respectively.
When I print list it consist of ' ' every elements of list
Thanks in Advance.
My code:
def high_and_low(numbers):
numbers = numbers.split()
numbers = list(numbers)
return max(numbers),min(numbers)
print high_and_low("4 5 29 54 4 0 -214 542 -64 1 -3 6 -6")
split returns strings, and you don't convert the strings to actual numbers. When comparing strings, the meaning of the comparison is different than when comparing numbers:
>>> '2' > '10'
True
So you need to change your function to something like this:
In [1]: def high_and_low(s):
...: numbers = [int(x) for x in s.split()]
...: return max(numbers), min(numbers)
...:
In [2]: high_and_low("4 5 29 54 4 0 -214 542 -64 1 -3 6 -6")
Out[2]: (542, -214)
min and max take a key so if you don't actually want ints returned you can use key=int so you compare as integers and not strings which is what you are currently doing:
def high_and_low(numbers):
numbers = numbers.split()
return max(numbers,key=int),min(numbers,key=int)
Or use map to cast the strings to int after splitting if you want ints:
def high_and_low(numbers):
numbers = map(int,numbers.split())
return max(numbers,key=int),min(numbers,key=int)
numbers is already a list after splitting so using numbers = list(numbers) is redundant.
from the docs:
sequence objects may be compared to other objects with the same sequence type. The comparison uses lexicographical ordering: first the first two items are compared, and if they differ this determines the outcome of the comparison; if they are equal, the next two items are compared, and so on, until either sequence is exhausted
So for min you only get the correct answer -214 because -2 is < -6 and -3, once you add -1 or anything starting with -1 then you would again see incorrect output.
For the max you get '6' because "6" is greater than the first char of any other substring.