r/learnpython • u/Important_Rip6864 • Aug 02 '24
What's wrong with the max module of python ?
The answer of this code is wrong. The output is supposed to be 25 but for some reason it's 9.
Code:
list=['9', '12', '8', '25', '23']
biggest_number=max(list)
print(biggest_number)
I tried the following code with the following input in different IDE's but every single one of them gave the same answer, maybe the max module is taking the 9 as 90. Any comments or help would be appreciated to solve this issue.
131
u/danielroseman Aug 02 '24
These are strings. Strings are always compared lexicographically.
If you want to compare numerically, use numbers, ie ints.
3
u/whitelife123 Aug 03 '24
Funnily enough in JavaScript, ints are still compared lexicographically. You have to pass a lambda to get them to compare numerically
1
u/JohnnyJordaan Aug 03 '24
Not just 'in JavaScript' in general, as the < and > work just as you would expect, numerically. It's that many sequence methods, like Array.sort, work exclusively lexicographically (as from JS principles, dynamic behavior based on the type makes less sense). But when talking a max() equivalent, you would rather use Math.max() and that works, as the name suggests, numerically too.
1
u/whitelife123 Aug 04 '24
Ah, thanks for the clarification, it's been a while since I've done data wrangling in JS. Learned this tidbit when I was working on a dataviz project
93
u/cyberjellyfish Aug 02 '24
You've gotten good answers, but I'm going to give you some advice that will serve you well:
Everyone occasionally gets to a point where they think something in the standard library or a ubiquitously used library is obviously broken.
It's not broken. You're the problem. Go back and validate your assumptions. Take a break and come back. 99.99999% of the time you'll find a simple mistake in your own code.
This happens to and the advice applies to every developer, at every experience level.
24
u/Skirlaxx Aug 02 '24
That's a good advice. Though I think op knows it and just didn't want to accept it. It's like when at 1:30 am, I still try to blame my model errors on pytorch, because I refuse to accept I made a mistake somewhere and probably shouldn't be coding at 1:30 am to begin with, since I can barely remember what file I am in and what it is I am trying to do.
4
6
u/CraigAT Aug 02 '24
I too have a little chuckle when I see posts like this one. Partly because I have been there myself, you have been struggling with an issue for so long and have tried all sorts of things, but it just doesn't appear to be doing what you think it should.
It's natural that when you have exhausted all other possibilities, the one that remains has to be the solution.
But in almost all cases regarding the Python standard libraries, they are not wrong. Their code and outcomes have been tested billions of times by both users and programmatically by unit tests etc.
I think alongside errors in your code, probably just as many issues are down to not truly understanding the implementation of the function they are using - often the developer made sane decisions for cases you never thought of, which means it may not work how you expect it to.
1
u/ryoko227 Aug 02 '24
Absolutely this. I'm a learner, and I cannot count how many times I have written something that "I knew was right," only to have it be some silly mistake I had made.
This actually happened this morning in VSC. My indents were getting an extra space after writing if or for loops. Seems somewhere further up in the code I had indented something that was not error generating, but enough for VSC to behave unexpectedly.
-1
u/bot_exe Aug 03 '24
Also he could have just asked any LLM and gotten a simple explanation instantly. Testing on multiple IDEs and even making this thread was a waste of time.
26
u/JohnnyJordaan Aug 02 '24
The answer of this code is wrong
The answer is correct
What's wrong with the max module of python
It's a function and there's nothing wrong with it.
Please consider the origin of the problem to be between your keyboard and your chair, not with a programming language maintained and further expanded by hundreds of developers. Just because you don't immediately understand why max() sorts strings differently than ints, means you need to understand why it works that way.
6
Aug 02 '24
Thank you. The tendency of beginners to assume the machine is somehow doing something wrong is absolutely beyond my understanding. Smells of insane levels of hubris.
15
Aug 02 '24
You have your answer so I will address this title.
What's wrong with the max module of python ?
Get out of this habit immediately. It is overwhelmingly unlikely that you have discovered a real problem with the builtin library code. You should get into the mindset of "what am I missing", not "why is the language wrong", because it will be the former 99.99999% of the time. Especially as a beginner, the idea that the module is somehow wrong sounds like an unbelievable level of hubris.
The language is basically never wrong. It literally always does exactly what you tell it.
1
u/bhonbeg Aug 04 '24
Lol your answer is like coincidentally and not AI-identally the same as cyberjellyfish except they provided the 99.999999 with 6 nines after the decimal point. We are all fucking clones!
6
u/UsernameTaken1701 Aug 02 '24
Try print(sorted(listNums)) and see what you get.
Now try print(sorted([int(i) for i in listNums])) . Your list items have to be made into integers to work with max() the way you want..
Also, don't use list as a variable name. It's a data type, and also a function list() that can make lists from iterable objects like strings. It's weird it's not a reserved word.
2
u/__nickerbocker__ Aug 02 '24
Emphasizing: never use built-in symbols as variable names. You will do it and you will spend a good amount of time debugging and you will remember this advice. Also, you can simply pass int for a bit cleaner version:
sorted_list = sorted(str_nums, key=int)
2
u/UsernameTaken1701 Aug 03 '24
Oh, yeah, that is a much nicer approach--don't even have to convert it to
intDon't even need a new list if you just drop it in asprint(sorted(str_nums, key=int)). Thanks, TIL.
4
u/Binary101010 Aug 02 '24
The answer of this code is wrong.
Strings are sorted lexicographically, and what that means for strings starting with digits is that all of the first digits are compared: "8" is greater than "7" etc. If there's a tie on the first digit then the second digits of those involved in the tie are compared, and so on.
As the list you provided to max() consisted only of strings, it returned the correct answer for that list.
If your intent was to have these items compared in the way you'd expect integers to be compared, then you need to pass it a list of integers.
list = [9,12,8,25,23]4
u/SisyphusAndMyBoulder Aug 02 '24
What's wrong with the max module of python ?
Word of advice? If you're using a built-in function or importing something and it's not working as expected, chances are you're doing something wrong & the function is working exactly as it should be.
I find it much easier to debug when I assume I did something wrong instead of assuming a core library is misbehaving.
3
u/Altrooke Aug 02 '24
And THANK GOD python works likes this. I can only imagine what a mess it would be if python tried to infer the types based on string content.
3
Aug 02 '24
Nothing is wrong with it, you're just not comparing numbers.
Which is greater? "Dictionary" or "abracadabra"?
1
1
u/CrusaderGOT Aug 02 '24
First convert your list of strings to list of ints, like, int_list = [int(num) for num in list] Then perform your operation. But this isn't the optimal way.
First don't name your variables the same as any python globals, in your case list should be something like str_list .
Also just save the elements in your list as ints to avoid all this, you can use the int() function to convert them from their incoming source if any. Using a list comprehension to convert them becomes difficult if the elements in your list are super plenty.
1
u/Rinzwind Aug 02 '24
to convert a list of strings into integers
[int(x) for x in list]
[int(x) for x in list]1
1
u/BalStrate Aug 02 '24
They're considered as strings Comparison in strings are done on the first character, and in case they're equal, it goes to the second character and so on
In fact '9'>'12' since '9'>'1'
1
u/six4one Aug 03 '24
Another mistake you've made that doesn't affect your code now, but later on, you'll find yourself getting weird bugs, naming the list "list". You should give it a different name that's not a Python keyword, function, or module name that you've imported. Otherwise, if you try to convert something to a list, eg
list("1234")
Expected output:
["1", "2", "3", "4"]
Instead, you will get the following error:
TypeError: "list" object is not callable
0
u/xrsly Aug 02 '24 edited Aug 02 '24
input() will always return a string, so if you expect the input to be a list of integers, then you have to validate and convert each "number" to an int. Perhaps like this:
numbers_as_string = input("Please enter a series of numbers (e.g.: 1, 2, 3): ")
try:
numbers = [int(num) for num in string_of_numbers.split()]
except ValueError:
raise ValueError(f"Some numbers were not valid: {[i for i in numbers_as_strings.split() if i.isdigit() is False]}"}NOTE: There are many ways to solve this, this is just an example.
Breakdown of the code:
First we take the input from the user (remember that this will always be a string no matter what)
Then we use the try/except statement, which basically just means that we are going to try to do something, and if a certain error occurs, then we can "catch" it and write our own error message for it. If we try to convert a non-number to an int, then a ValueError occurs, so we write "except ValueError:" to catch that specific error.
In this case, we will try to convert each "word" in the string to a number, so that e.g., "42" becomes 42. Note that split() will take any string and return a list of words (space will be used as a separator by default, so "hello 42" becomes ["hello", "42"], whereas "hello_42" becomes ["hello_42"], since there is no space. Now, if the user enters something that's not a number, then the error message will tell them that some "words" were not valid numbers. So "hello 42" would result in the error: "ValueError: Some numbers were not valid: ["hello"]. You can write whatever error message you want of course.
If the user entered only valid numbers, then the result will be e.g., "42 21 11" -> [42, 21, 11]
Now you have a list of integers, so you can use max(numbers) to find the biggest one.
22
u/[deleted] Aug 02 '24 edited Aug 02 '24
Run this code to see the problem in action: