def AddDictionary(s):
i = 0
result = {}
for c in s:
result[c] = i
if result.has_key(c):
i += 1
return result
def theMostRepeated(s):
if len(s) == 0:
return "The list is empty"
else:
keys = AddDictionary(s).keys()
mx = keys[0]
for key in keys:
if AddDictionary(s)[key] > AddDictionary(s)[mx]: #Al comparar las keys no se comparan los numeros sino los valores a los que se refieren
mx = key
return mx
What this code does is count the times a number appears in a list. If the list is empty, it puts the message "the list is empty" and what fails me is that I don't know how, taking advantage of the functions that I have done, I can make it so that if two numbers are repeated the same number of times, it returns the first one that comes out on the list. An example of the function would be this: print theMostRepeated([1, 2, 2, 3, 3])
Regardless of what you ask, there is a design flaw in your code, and some inefficiencies.
AddDictionary()
Let's start with the function
AddDictionary()
. It is understood that the objective of this function is to receive a list and build a dictionary whose keys are the elements of the list and the values are the number of times that element appears in the list, right?First a detail. I see that you use it
result.has_key(c)
to see if a key is in a dictionary or not. This syntax is from Python 2, in Python 3 it has been removed. It is recommended that you usec in result
to achieve the same goal, a syntax that is valid in any version of Python.On the other hand I think the function does not do what you intended. Let's take the list for example
[20,20,30,30]
. If you call your function with that list, instead of the expected result{20: 2, 30: 2}
you get{20: 1, 30: 3}
. Why is understood if you mentally execute the "step by step" function.i=0
andresult={}
c
it is worth 20, while iti
is worth 0. Soresult[20]=0
you do , which is already wrong, since you should count that 2 has come out once, but you assign 0 instead.20
's in the dictionary. But it will always be there because you just put it on the line above! This test is therefore superfluous, and the following linei+=1
will always be executed.c
is again20
, so you assign aresult[20]
the new value ofi
which is 1. It's still wrong. And then you incrementi
, which becomes 2.30
and you doresult[30]=2
.i+=1
is always executed, basicallyi
it does not count how many times each number has appeared (a single counter could not do that), but how many times we have iterated in the loop.result[30]=3
You can't have just one accountant. You need one for each possible value in the list. But precisely those counters are the ones you keep in the dictionary. Therefore the corrected version of your code would be:
theMostRepeated()
I understand that the purpose of this function is to return the element that has been repeated the most times. Therefore, which is the dictionary key that has a greater value.
Your implementation unnecessarily calls
AddDictionary()
many times. Actually, it is enough that you call it once and store the result to later operate on that result. That is, you can do this other:On the other hand I have done
list()
aroundresult.keys()
to make it compatible with Python 3, because in this version of Pythonresult.keys()
it is no longer a list, but a generator.Your question
How to make that if there are elements that are repeated the same number of times, the result is the one that appears first in the list?
This would imply having a dictionary that maintains the insertion order. Since the elements are inserted in the order in which they are found in the list, if we had a dictionary that would preserve that order (that is, when you do it,
diccionario.keys()
it returns the keys in the same order in which they were inserted) your problem would be solved. , since the maximum that you would be left with would correspond to the first value that appeared.Unfortunately in Python 2 dictionaries do not preserve insertion order. That is, when you get
diccionario.keys()
the keys they come in any unpredictable order (it can even be different each time you run the program with the same data). As of Python 3.7 the insertion order in dictionaries is preserved, so if you run the above code with Python 3.7 it would already work as expected without having to do anything.For lower versions of python we have the type
OrderedDict
available even for Python 2.Using this type, it would suffice to rewrite the function
AddDictionary()
like this:And it will work as you expect:
Another way
Without the need to introduce
OrderedDict()
but only using the types that you already had in your code, another solution may be that youtheMostRepeated()
iterate through the elements of the list instead of the keys of the dictionary.So:
The code is even more readable, but this version is more inefficient than the previous one, since the loop must iterate through more elements (the list will generally have more elements than there were keys in the dictionary, especially if the data is repeated many times). ).