Most frequent integer in a list












4












$begingroup$


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









$endgroup$








  • 1




    $begingroup$
    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!)
    $endgroup$
    – chatton
    Jan 27 '18 at 23:48






  • 1




    $begingroup$
    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.
    $endgroup$
    – msanford
    Jan 29 '18 at 14:49


















4












$begingroup$


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









$endgroup$








  • 1




    $begingroup$
    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!)
    $endgroup$
    – chatton
    Jan 27 '18 at 23:48






  • 1




    $begingroup$
    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.
    $endgroup$
    – msanford
    Jan 29 '18 at 14:49
















4












4








4





$begingroup$


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









$endgroup$




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)






python beginner






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 27 '18 at 23:00









Anonymous3.1415Anonymous3.1415

424214




424214








  • 1




    $begingroup$
    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!)
    $endgroup$
    – chatton
    Jan 27 '18 at 23:48






  • 1




    $begingroup$
    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.
    $endgroup$
    – msanford
    Jan 29 '18 at 14:49
















  • 1




    $begingroup$
    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!)
    $endgroup$
    – chatton
    Jan 27 '18 at 23:48






  • 1




    $begingroup$
    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.
    $endgroup$
    – msanford
    Jan 29 '18 at 14:49










1




1




$begingroup$
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!)
$endgroup$
– chatton
Jan 27 '18 at 23:48




$begingroup$
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!)
$endgroup$
– chatton
Jan 27 '18 at 23:48




1




1




$begingroup$
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.
$endgroup$
– msanford
Jan 29 '18 at 14:49






$begingroup$
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.
$endgroup$
– msanford
Jan 29 '18 at 14:49












2 Answers
2






active

oldest

votes


















5












$begingroup$

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











$endgroup$









  • 1




    $begingroup$
    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])
    $endgroup$
    – Gareth Rees
    Jan 29 '18 at 14:06












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










  • $begingroup$
    @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.
    $endgroup$
    – Graipher
    Jan 29 '18 at 14:34






  • 1




    $begingroup$
    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.
    $endgroup$
    – Gareth Rees
    Jan 29 '18 at 14:43



















5












$begingroup$

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









$endgroup$













    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',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    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















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    5












    $begingroup$

    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











    $endgroup$









    • 1




      $begingroup$
      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])
      $endgroup$
      – Gareth Rees
      Jan 29 '18 at 14:06












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










    • $begingroup$
      @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.
      $endgroup$
      – Graipher
      Jan 29 '18 at 14:34






    • 1




      $begingroup$
      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.
      $endgroup$
      – Gareth Rees
      Jan 29 '18 at 14:43
















    5












    $begingroup$

    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











    $endgroup$









    • 1




      $begingroup$
      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])
      $endgroup$
      – Gareth Rees
      Jan 29 '18 at 14:06












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










    • $begingroup$
      @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.
      $endgroup$
      – Graipher
      Jan 29 '18 at 14:34






    • 1




      $begingroup$
      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.
      $endgroup$
      – Gareth Rees
      Jan 29 '18 at 14:43














    5












    5








    5





    $begingroup$

    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











    $endgroup$



    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 '18 at 14:30

























    answered Jan 29 '18 at 13:59









    GraipherGraipher

    26.5k54092




    26.5k54092








    • 1




      $begingroup$
      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])
      $endgroup$
      – Gareth Rees
      Jan 29 '18 at 14:06












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










    • $begingroup$
      @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.
      $endgroup$
      – Graipher
      Jan 29 '18 at 14:34






    • 1




      $begingroup$
      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.
      $endgroup$
      – Gareth Rees
      Jan 29 '18 at 14:43














    • 1




      $begingroup$
      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])
      $endgroup$
      – Gareth Rees
      Jan 29 '18 at 14:06












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










    • $begingroup$
      @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.
      $endgroup$
      – Graipher
      Jan 29 '18 at 14:34






    • 1




      $begingroup$
      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.
      $endgroup$
      – Gareth Rees
      Jan 29 '18 at 14:43








    1




    1




    $begingroup$
    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])
    $endgroup$
    – Gareth Rees
    Jan 29 '18 at 14:06






    $begingroup$
    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])
    $endgroup$
    – Gareth Rees
    Jan 29 '18 at 14:06














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




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












    $begingroup$
    @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.
    $endgroup$
    – Graipher
    Jan 29 '18 at 14:34




    $begingroup$
    @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.
    $endgroup$
    – Graipher
    Jan 29 '18 at 14:34




    1




    1




    $begingroup$
    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.
    $endgroup$
    – Gareth Rees
    Jan 29 '18 at 14:43




    $begingroup$
    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.
    $endgroup$
    – Gareth Rees
    Jan 29 '18 at 14:43













    5












    $begingroup$

    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









    $endgroup$


















      5












      $begingroup$

      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









      $endgroup$
















        5












        5








        5





        $begingroup$

        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









        $endgroup$



        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 '18 at 23:35









        Oscar SmithOscar Smith

        2,9331123




        2,9331123






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.




            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















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            How to reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

            is 'sed' thread safe

            How to make a Squid Proxy server?