Most frequent integer in a list

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
4
down vote

favorite












Here was my attempt at finding the most frequent integers in a list, I feel like there are better ways to do this and I spent a great deal of time coming up with this solution, so please point me in the correct direction!



'''
Created on Jan 27, 2018
Problem statement: Find the most frequently occuring integer in a list and its occurence;
input: 1 1 2 3 2 1 2
output: [(1,3), (2, 3)]

@author: Anonymous3.1415
'''
from collections import Counter

def integer_frequency(int_list):
int_freq = Counter()
for i in int_list:
int_freq[i] += 1
cnt = 0
values = sorted(int_freq.values())
values.reverse()
for x in values:
if x == values[0]:
cnt += 1
else:
break
return int_freq.most_common(cnt)



int_list = list(map(int, raw_input().strip().split(' ')))
most_frequent = integer_frequency(int_list)
print(most_frequent)






share|improve this question















  • 1




    watch out for an empty input list. There's currently no validation in place and it will raise a ValueError (unless the problem states your input will always be non-empty!)
    – chatton
    Jan 27 at 23:48






  • 1




    Somewhat trivial, but since I think documentation is important: occurrence, occurring take two 2 rs. As a matter of habit, spelling matters. I work in a trilingual office, and I can't tell you the number of times we've missed parts of a length refactoring because half of us write it phonetically (in our accent) as lenght.
    – msanford
    Jan 29 at 14:49

















up vote
4
down vote

favorite












Here was my attempt at finding the most frequent integers in a list, I feel like there are better ways to do this and I spent a great deal of time coming up with this solution, so please point me in the correct direction!



'''
Created on Jan 27, 2018
Problem statement: Find the most frequently occuring integer in a list and its occurence;
input: 1 1 2 3 2 1 2
output: [(1,3), (2, 3)]

@author: Anonymous3.1415
'''
from collections import Counter

def integer_frequency(int_list):
int_freq = Counter()
for i in int_list:
int_freq[i] += 1
cnt = 0
values = sorted(int_freq.values())
values.reverse()
for x in values:
if x == values[0]:
cnt += 1
else:
break
return int_freq.most_common(cnt)



int_list = list(map(int, raw_input().strip().split(' ')))
most_frequent = integer_frequency(int_list)
print(most_frequent)






share|improve this question















  • 1




    watch out for an empty input list. There's currently no validation in place and it will raise a ValueError (unless the problem states your input will always be non-empty!)
    – chatton
    Jan 27 at 23:48






  • 1




    Somewhat trivial, but since I think documentation is important: occurrence, occurring take two 2 rs. As a matter of habit, spelling matters. I work in a trilingual office, and I can't tell you the number of times we've missed parts of a length refactoring because half of us write it phonetically (in our accent) as lenght.
    – msanford
    Jan 29 at 14:49













up vote
4
down vote

favorite









up vote
4
down vote

favorite











Here was my attempt at finding the most frequent integers in a list, I feel like there are better ways to do this and I spent a great deal of time coming up with this solution, so please point me in the correct direction!



'''
Created on Jan 27, 2018
Problem statement: Find the most frequently occuring integer in a list and its occurence;
input: 1 1 2 3 2 1 2
output: [(1,3), (2, 3)]

@author: Anonymous3.1415
'''
from collections import Counter

def integer_frequency(int_list):
int_freq = Counter()
for i in int_list:
int_freq[i] += 1
cnt = 0
values = sorted(int_freq.values())
values.reverse()
for x in values:
if x == values[0]:
cnt += 1
else:
break
return int_freq.most_common(cnt)



int_list = list(map(int, raw_input().strip().split(' ')))
most_frequent = integer_frequency(int_list)
print(most_frequent)






share|improve this question











Here was my attempt at finding the most frequent integers in a list, I feel like there are better ways to do this and I spent a great deal of time coming up with this solution, so please point me in the correct direction!



'''
Created on Jan 27, 2018
Problem statement: Find the most frequently occuring integer in a list and its occurence;
input: 1 1 2 3 2 1 2
output: [(1,3), (2, 3)]

@author: Anonymous3.1415
'''
from collections import Counter

def integer_frequency(int_list):
int_freq = Counter()
for i in int_list:
int_freq[i] += 1
cnt = 0
values = sorted(int_freq.values())
values.reverse()
for x in values:
if x == values[0]:
cnt += 1
else:
break
return int_freq.most_common(cnt)



int_list = list(map(int, raw_input().strip().split(' ')))
most_frequent = integer_frequency(int_list)
print(most_frequent)








share|improve this question










share|improve this question




share|improve this question









asked Jan 27 at 23:00









Anonymous3.1415

376212




376212







  • 1




    watch out for an empty input list. There's currently no validation in place and it will raise a ValueError (unless the problem states your input will always be non-empty!)
    – chatton
    Jan 27 at 23:48






  • 1




    Somewhat trivial, but since I think documentation is important: occurrence, occurring take two 2 rs. As a matter of habit, spelling matters. I work in a trilingual office, and I can't tell you the number of times we've missed parts of a length refactoring because half of us write it phonetically (in our accent) as lenght.
    – msanford
    Jan 29 at 14:49













  • 1




    watch out for an empty input list. There's currently no validation in place and it will raise a ValueError (unless the problem states your input will always be non-empty!)
    – chatton
    Jan 27 at 23:48






  • 1




    Somewhat trivial, but since I think documentation is important: occurrence, occurring take two 2 rs. As a matter of habit, spelling matters. I work in a trilingual office, and I can't tell you the number of times we've missed parts of a length refactoring because half of us write it phonetically (in our accent) as lenght.
    – msanford
    Jan 29 at 14:49








1




1




watch out for an empty input list. There's currently no validation in place and it will raise a ValueError (unless the problem states your input will always be non-empty!)
– chatton
Jan 27 at 23:48




watch out for an empty input list. There's currently no validation in place and it will raise a ValueError (unless the problem states your input will always be non-empty!)
– chatton
Jan 27 at 23:48




1




1




Somewhat trivial, but since I think documentation is important: occurrence, occurring take two 2 rs. As a matter of habit, spelling matters. I work in a trilingual office, and I can't tell you the number of times we've missed parts of a length refactoring because half of us write it phonetically (in our accent) as lenght.
– msanford
Jan 29 at 14:49





Somewhat trivial, but since I think documentation is important: occurrence, occurring take two 2 rs. As a matter of habit, spelling matters. I work in a trilingual office, and I can't tell you the number of times we've missed parts of a length refactoring because half of us write it phonetically (in our accent) as lenght.
– msanford
Jan 29 at 14:49











2 Answers
2






active

oldest

votes

















up vote
5
down vote



accepted










You could use itertools.takewhile to keep on taking tuples until they are not the same count anymore:



from collections import Counter
from itertools import takewhile

def integer_frequency(integers):
int_freq = Counter(integers)
most_common = int_freq.most_common(1)[0]
return list(takewhile(lambda x: x[1] == most_common[1],
int_freq.most_common()))


I also renamed your integer_list to integers, because it can be any iterable of integers.



Alternatively, you could use itertools.groupby to group the tuples by their frequency and return the group with the highest frequency, as @Gareth Reese has suggested in the comments:



from collections import Counter
from itertools import groupby

def integer_frequency(integers):
return list(next(groupby(Counter(integers).most_common(),
key=lambda x: x[1]))[1])


This approach is consistently faster (by a small amount):



enter image description here



However, both beat your algorithm by quite a lot:



enter image description here






share|improve this answer



















  • 1




    If you're going down the itertools route, I think groupby would be a little bit clearer than takewhile. That is, list(next(groupby(Counter(integers).most_common(), key=lambda x:x[1]))[1])
    – Gareth Rees
    Jan 29 at 14:06











  • @GarethRees Not sure if it is any clearer with those nested calls, but it is a nice alternative. I added it to the answer.
    – Graipher
    Jan 29 at 14:12










  • @GarethRees Added some timings and groupby seems to be consistently faster than takewhile (but not by much). Both are a lot better than the OP's approach, though.
    – Graipher
    Jan 29 at 14:34






  • 1




    In real code you'd use variables instead of nested function applications, but I only have this little comment box to type into! The reason why the groupby approach is faster is that it avoids a duplicate call to most_common.
    – Gareth Rees
    Jan 29 at 14:43

















up vote
5
down vote













There are some things that will make this code cleaner and faster. int_freq = Counter(int_list) will automatically initialize the counter without you doing work. Also values = sorted(int_freq.values(), reverse=True) will be cleaner and faster. Other than that this looks pretty good.






share|improve this answer





















    Your Answer




    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186162%2fmost-frequent-integer-in-a-list%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    5
    down vote



    accepted










    You could use itertools.takewhile to keep on taking tuples until they are not the same count anymore:



    from collections import Counter
    from itertools import takewhile

    def integer_frequency(integers):
    int_freq = Counter(integers)
    most_common = int_freq.most_common(1)[0]
    return list(takewhile(lambda x: x[1] == most_common[1],
    int_freq.most_common()))


    I also renamed your integer_list to integers, because it can be any iterable of integers.



    Alternatively, you could use itertools.groupby to group the tuples by their frequency and return the group with the highest frequency, as @Gareth Reese has suggested in the comments:



    from collections import Counter
    from itertools import groupby

    def integer_frequency(integers):
    return list(next(groupby(Counter(integers).most_common(),
    key=lambda x: x[1]))[1])


    This approach is consistently faster (by a small amount):



    enter image description here



    However, both beat your algorithm by quite a lot:



    enter image description here






    share|improve this answer



















    • 1




      If you're going down the itertools route, I think groupby would be a little bit clearer than takewhile. That is, list(next(groupby(Counter(integers).most_common(), key=lambda x:x[1]))[1])
      – Gareth Rees
      Jan 29 at 14:06











    • @GarethRees Not sure if it is any clearer with those nested calls, but it is a nice alternative. I added it to the answer.
      – Graipher
      Jan 29 at 14:12










    • @GarethRees Added some timings and groupby seems to be consistently faster than takewhile (but not by much). Both are a lot better than the OP's approach, though.
      – Graipher
      Jan 29 at 14:34






    • 1




      In real code you'd use variables instead of nested function applications, but I only have this little comment box to type into! The reason why the groupby approach is faster is that it avoids a duplicate call to most_common.
      – Gareth Rees
      Jan 29 at 14:43














    up vote
    5
    down vote



    accepted










    You could use itertools.takewhile to keep on taking tuples until they are not the same count anymore:



    from collections import Counter
    from itertools import takewhile

    def integer_frequency(integers):
    int_freq = Counter(integers)
    most_common = int_freq.most_common(1)[0]
    return list(takewhile(lambda x: x[1] == most_common[1],
    int_freq.most_common()))


    I also renamed your integer_list to integers, because it can be any iterable of integers.



    Alternatively, you could use itertools.groupby to group the tuples by their frequency and return the group with the highest frequency, as @Gareth Reese has suggested in the comments:



    from collections import Counter
    from itertools import groupby

    def integer_frequency(integers):
    return list(next(groupby(Counter(integers).most_common(),
    key=lambda x: x[1]))[1])


    This approach is consistently faster (by a small amount):



    enter image description here



    However, both beat your algorithm by quite a lot:



    enter image description here






    share|improve this answer



















    • 1




      If you're going down the itertools route, I think groupby would be a little bit clearer than takewhile. That is, list(next(groupby(Counter(integers).most_common(), key=lambda x:x[1]))[1])
      – Gareth Rees
      Jan 29 at 14:06











    • @GarethRees Not sure if it is any clearer with those nested calls, but it is a nice alternative. I added it to the answer.
      – Graipher
      Jan 29 at 14:12










    • @GarethRees Added some timings and groupby seems to be consistently faster than takewhile (but not by much). Both are a lot better than the OP's approach, though.
      – Graipher
      Jan 29 at 14:34






    • 1




      In real code you'd use variables instead of nested function applications, but I only have this little comment box to type into! The reason why the groupby approach is faster is that it avoids a duplicate call to most_common.
      – Gareth Rees
      Jan 29 at 14:43












    up vote
    5
    down vote



    accepted







    up vote
    5
    down vote



    accepted






    You could use itertools.takewhile to keep on taking tuples until they are not the same count anymore:



    from collections import Counter
    from itertools import takewhile

    def integer_frequency(integers):
    int_freq = Counter(integers)
    most_common = int_freq.most_common(1)[0]
    return list(takewhile(lambda x: x[1] == most_common[1],
    int_freq.most_common()))


    I also renamed your integer_list to integers, because it can be any iterable of integers.



    Alternatively, you could use itertools.groupby to group the tuples by their frequency and return the group with the highest frequency, as @Gareth Reese has suggested in the comments:



    from collections import Counter
    from itertools import groupby

    def integer_frequency(integers):
    return list(next(groupby(Counter(integers).most_common(),
    key=lambda x: x[1]))[1])


    This approach is consistently faster (by a small amount):



    enter image description here



    However, both beat your algorithm by quite a lot:



    enter image description here






    share|improve this answer















    You could use itertools.takewhile to keep on taking tuples until they are not the same count anymore:



    from collections import Counter
    from itertools import takewhile

    def integer_frequency(integers):
    int_freq = Counter(integers)
    most_common = int_freq.most_common(1)[0]
    return list(takewhile(lambda x: x[1] == most_common[1],
    int_freq.most_common()))


    I also renamed your integer_list to integers, because it can be any iterable of integers.



    Alternatively, you could use itertools.groupby to group the tuples by their frequency and return the group with the highest frequency, as @Gareth Reese has suggested in the comments:



    from collections import Counter
    from itertools import groupby

    def integer_frequency(integers):
    return list(next(groupby(Counter(integers).most_common(),
    key=lambda x: x[1]))[1])


    This approach is consistently faster (by a small amount):



    enter image description here



    However, both beat your algorithm by quite a lot:



    enter image description here







    share|improve this answer















    share|improve this answer



    share|improve this answer








    edited Jan 29 at 14:30


























    answered Jan 29 at 13:59









    Graipher

    20.5k43081




    20.5k43081







    • 1




      If you're going down the itertools route, I think groupby would be a little bit clearer than takewhile. That is, list(next(groupby(Counter(integers).most_common(), key=lambda x:x[1]))[1])
      – Gareth Rees
      Jan 29 at 14:06











    • @GarethRees Not sure if it is any clearer with those nested calls, but it is a nice alternative. I added it to the answer.
      – Graipher
      Jan 29 at 14:12










    • @GarethRees Added some timings and groupby seems to be consistently faster than takewhile (but not by much). Both are a lot better than the OP's approach, though.
      – Graipher
      Jan 29 at 14:34






    • 1




      In real code you'd use variables instead of nested function applications, but I only have this little comment box to type into! The reason why the groupby approach is faster is that it avoids a duplicate call to most_common.
      – Gareth Rees
      Jan 29 at 14:43












    • 1




      If you're going down the itertools route, I think groupby would be a little bit clearer than takewhile. That is, list(next(groupby(Counter(integers).most_common(), key=lambda x:x[1]))[1])
      – Gareth Rees
      Jan 29 at 14:06











    • @GarethRees Not sure if it is any clearer with those nested calls, but it is a nice alternative. I added it to the answer.
      – Graipher
      Jan 29 at 14:12










    • @GarethRees Added some timings and groupby seems to be consistently faster than takewhile (but not by much). Both are a lot better than the OP's approach, though.
      – Graipher
      Jan 29 at 14:34






    • 1




      In real code you'd use variables instead of nested function applications, but I only have this little comment box to type into! The reason why the groupby approach is faster is that it avoids a duplicate call to most_common.
      – Gareth Rees
      Jan 29 at 14:43







    1




    1




    If you're going down the itertools route, I think groupby would be a little bit clearer than takewhile. That is, list(next(groupby(Counter(integers).most_common(), key=lambda x:x[1]))[1])
    – Gareth Rees
    Jan 29 at 14:06





    If you're going down the itertools route, I think groupby would be a little bit clearer than takewhile. That is, list(next(groupby(Counter(integers).most_common(), key=lambda x:x[1]))[1])
    – Gareth Rees
    Jan 29 at 14:06













    @GarethRees Not sure if it is any clearer with those nested calls, but it is a nice alternative. I added it to the answer.
    – Graipher
    Jan 29 at 14:12




    @GarethRees Not sure if it is any clearer with those nested calls, but it is a nice alternative. I added it to the answer.
    – Graipher
    Jan 29 at 14:12












    @GarethRees Added some timings and groupby seems to be consistently faster than takewhile (but not by much). Both are a lot better than the OP's approach, though.
    – Graipher
    Jan 29 at 14:34




    @GarethRees Added some timings and groupby seems to be consistently faster than takewhile (but not by much). Both are a lot better than the OP's approach, though.
    – Graipher
    Jan 29 at 14:34




    1




    1




    In real code you'd use variables instead of nested function applications, but I only have this little comment box to type into! The reason why the groupby approach is faster is that it avoids a duplicate call to most_common.
    – Gareth Rees
    Jan 29 at 14:43




    In real code you'd use variables instead of nested function applications, but I only have this little comment box to type into! The reason why the groupby approach is faster is that it avoids a duplicate call to most_common.
    – Gareth Rees
    Jan 29 at 14:43












    up vote
    5
    down vote













    There are some things that will make this code cleaner and faster. int_freq = Counter(int_list) will automatically initialize the counter without you doing work. Also values = sorted(int_freq.values(), reverse=True) will be cleaner and faster. Other than that this looks pretty good.






    share|improve this answer

























      up vote
      5
      down vote













      There are some things that will make this code cleaner and faster. int_freq = Counter(int_list) will automatically initialize the counter without you doing work. Also values = sorted(int_freq.values(), reverse=True) will be cleaner and faster. Other than that this looks pretty good.






      share|improve this answer























        up vote
        5
        down vote










        up vote
        5
        down vote









        There are some things that will make this code cleaner and faster. int_freq = Counter(int_list) will automatically initialize the counter without you doing work. Also values = sorted(int_freq.values(), reverse=True) will be cleaner and faster. Other than that this looks pretty good.






        share|improve this answer













        There are some things that will make this code cleaner and faster. int_freq = Counter(int_list) will automatically initialize the counter without you doing work. Also values = sorted(int_freq.values(), reverse=True) will be cleaner and faster. Other than that this looks pretty good.







        share|improve this answer













        share|improve this answer



        share|improve this answer











        answered Jan 27 at 23:35









        Oscar Smith

        2,625922




        2,625922






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186162%2fmost-frequent-integer-in-a-list%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Chat program with C++ and SFML

            Function to Return a JSON Like Objects Using VBA Collections and Arrays

            Will my employers contract hold up in court?