Count the number of times an item occurs in each nested list











up vote
0
down vote

favorite
1












So I have a list of whether or not people won, drew or lost a game over each time they played:



scores = [["win","lose","win"],["win","win"],["draw","win"],["lose"]]


And I want to get a count of 'win' / 'lose' / 'draw' for each sublist



Can I do this using a dictionary?



e.g. dict= {[win:2, draw:0, lose:1],[win:2, draw:0, lose:0].....}



I tried counting and placing in a list by doing this:



countlose=0
for sublist in scores:
for item in sublist:
for item in range(len(sublist)):
if item=="lose":
countlose+=1
print(countlose)


But this just returned 0



Let me know how you would solve the problem










share|improve this question




















  • 6




    Neither the input nor the output are valid data structures
    – roganjosh
    Nov 9 at 13:10








  • 1




    range() will return integers, there will never be equal to "lose".
    – Sharku
    Nov 9 at 13:11










  • Relevant: collections.Counter.
    – 9769953
    Nov 9 at 13:12















up vote
0
down vote

favorite
1












So I have a list of whether or not people won, drew or lost a game over each time they played:



scores = [["win","lose","win"],["win","win"],["draw","win"],["lose"]]


And I want to get a count of 'win' / 'lose' / 'draw' for each sublist



Can I do this using a dictionary?



e.g. dict= {[win:2, draw:0, lose:1],[win:2, draw:0, lose:0].....}



I tried counting and placing in a list by doing this:



countlose=0
for sublist in scores:
for item in sublist:
for item in range(len(sublist)):
if item=="lose":
countlose+=1
print(countlose)


But this just returned 0



Let me know how you would solve the problem










share|improve this question




















  • 6




    Neither the input nor the output are valid data structures
    – roganjosh
    Nov 9 at 13:10








  • 1




    range() will return integers, there will never be equal to "lose".
    – Sharku
    Nov 9 at 13:11










  • Relevant: collections.Counter.
    – 9769953
    Nov 9 at 13:12













up vote
0
down vote

favorite
1









up vote
0
down vote

favorite
1






1





So I have a list of whether or not people won, drew or lost a game over each time they played:



scores = [["win","lose","win"],["win","win"],["draw","win"],["lose"]]


And I want to get a count of 'win' / 'lose' / 'draw' for each sublist



Can I do this using a dictionary?



e.g. dict= {[win:2, draw:0, lose:1],[win:2, draw:0, lose:0].....}



I tried counting and placing in a list by doing this:



countlose=0
for sublist in scores:
for item in sublist:
for item in range(len(sublist)):
if item=="lose":
countlose+=1
print(countlose)


But this just returned 0



Let me know how you would solve the problem










share|improve this question















So I have a list of whether or not people won, drew or lost a game over each time they played:



scores = [["win","lose","win"],["win","win"],["draw","win"],["lose"]]


And I want to get a count of 'win' / 'lose' / 'draw' for each sublist



Can I do this using a dictionary?



e.g. dict= {[win:2, draw:0, lose:1],[win:2, draw:0, lose:0].....}



I tried counting and placing in a list by doing this:



countlose=0
for sublist in scores:
for item in sublist:
for item in range(len(sublist)):
if item=="lose":
countlose+=1
print(countlose)


But this just returned 0



Let me know how you would solve the problem







python list dictionary counter






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 9 at 13:17









jpp

84.3k194897




84.3k194897










asked Nov 9 at 13:08









I. Evans

483




483








  • 6




    Neither the input nor the output are valid data structures
    – roganjosh
    Nov 9 at 13:10








  • 1




    range() will return integers, there will never be equal to "lose".
    – Sharku
    Nov 9 at 13:11










  • Relevant: collections.Counter.
    – 9769953
    Nov 9 at 13:12














  • 6




    Neither the input nor the output are valid data structures
    – roganjosh
    Nov 9 at 13:10








  • 1




    range() will return integers, there will never be equal to "lose".
    – Sharku
    Nov 9 at 13:11










  • Relevant: collections.Counter.
    – 9769953
    Nov 9 at 13:12








6




6




Neither the input nor the output are valid data structures
– roganjosh
Nov 9 at 13:10






Neither the input nor the output are valid data structures
– roganjosh
Nov 9 at 13:10






1




1




range() will return integers, there will never be equal to "lose".
– Sharku
Nov 9 at 13:11




range() will return integers, there will never be equal to "lose".
– Sharku
Nov 9 at 13:11












Relevant: collections.Counter.
– 9769953
Nov 9 at 13:12




Relevant: collections.Counter.
– 9769953
Nov 9 at 13:12












3 Answers
3






active

oldest

votes

















up vote
2
down vote













Your desired result isn't valid syntax. Most likely you want a list of dictionaries.



collections.Counter only counts values in an iterable; it does not count externally supplied keys unless you supply additional logic.



In this case, you can use a list comprehension, combining with an empty dictionary:



from collections import Counter

scores = [["win","lose","win"],["win","win"],["draw","win"],["lose"]]

empty = dict.fromkeys(('win', 'lose', 'draw'), 0)

res = [{**empty, **Counter(i)} for i in scores]

[{'draw': 0, 'lose': 1, 'win': 2},
{'draw': 0, 'lose': 0, 'win': 2},
{'draw': 1, 'lose': 0, 'win': 1},
{'draw': 0, 'lose': 1, 'win': 0}]





share|improve this answer





















  • Copying dictionaries for each item in the list comprehension seems pretty inefficient.
    – planetp
    Nov 10 at 9:41










  • @planetp, I disagree, time complexity is the same as cycling through the ('win', 'lose', 'draw') keys one at a time.
    – jpp
    Nov 10 at 11:50


















up vote
1
down vote













You could apply a list comprehension for every sublist from your given list.



Also, declare your own counter function which counts the number of appearances of one item from win, lose or draw.



scores = [["win","lose","win"],["win","win"],["draw","win"],["lose"]]
def get_number(sublist):
counter = {'win': 0, 'draw' : 0, 'lose': 0}
for item in sublist:
counter[item] += 1
return counter

result = [get_number(sublist) for sublist in scores]


Output



[{'win': 2, 'draw': 0, 'lose': 1}, 
{'win': 2, 'draw': 0, 'lose': 0},
{'win': 1, 'draw': 1, 'lose': 0},
{'win': 0, 'draw': 0, 'lose': 1}]





share|improve this answer






























    up vote
    1
    down vote














    Can I do this using a dictionary?




    You can use collections.Counter, which is a subclass of dict for counting hashable objects:



    >>> from collections import Counter
    >>> scores = [['win', 'lose', 'win'], ['win', 'win'], ['draw', 'win'], ['lose']]
    >>> counts = [Counter(score) for score in scores]
    >>> counts
    [Counter({'win': 2, 'lose': 1}), Counter({'win': 2}), Counter({'draw': 1, 'win': 1}), Counter({'lose': 1})]


    To add zero counts for missing keys you can use an additional loop:



    >>> for c in counts:
    ... for k in ('win', 'lose', 'draw'):
    ... c[k] = c.get(k, 0)
    ...
    >>> counts
    [Counter({'win': 2, 'lose': 1, 'draw': 0}), Counter({'win': 2, 'lose': 0, 'draw': 0}), Counter({'draw': 1, 'win': 1, 'lose': 0}), Counter({'lose': 1, 'win': 0, 'draw': 0})]


    Alternatively, you could wrap the counters with collections.defaultdict:



    >>> counts = [defaultdict(int, Counter(score)) for score in scores]
    >>> counts
    [defaultdict(<class 'int'>, {'win': 2, 'lose': 1}), defaultdict(<class 'int'>, {'win': 2}), defaultdict(<class 'int'>, {'draw': 1, 'win': 1}), defaultdict(<class 'int'>, {'lose': 1})]
    >>> counts[0]['draw']
    0





    share|improve this answer























      Your Answer






      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: "1"
      };
      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: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      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%2fstackoverflow.com%2fquestions%2f53226311%2fcount-the-number-of-times-an-item-occurs-in-each-nested-list%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      2
      down vote













      Your desired result isn't valid syntax. Most likely you want a list of dictionaries.



      collections.Counter only counts values in an iterable; it does not count externally supplied keys unless you supply additional logic.



      In this case, you can use a list comprehension, combining with an empty dictionary:



      from collections import Counter

      scores = [["win","lose","win"],["win","win"],["draw","win"],["lose"]]

      empty = dict.fromkeys(('win', 'lose', 'draw'), 0)

      res = [{**empty, **Counter(i)} for i in scores]

      [{'draw': 0, 'lose': 1, 'win': 2},
      {'draw': 0, 'lose': 0, 'win': 2},
      {'draw': 1, 'lose': 0, 'win': 1},
      {'draw': 0, 'lose': 1, 'win': 0}]





      share|improve this answer





















      • Copying dictionaries for each item in the list comprehension seems pretty inefficient.
        – planetp
        Nov 10 at 9:41










      • @planetp, I disagree, time complexity is the same as cycling through the ('win', 'lose', 'draw') keys one at a time.
        – jpp
        Nov 10 at 11:50















      up vote
      2
      down vote













      Your desired result isn't valid syntax. Most likely you want a list of dictionaries.



      collections.Counter only counts values in an iterable; it does not count externally supplied keys unless you supply additional logic.



      In this case, you can use a list comprehension, combining with an empty dictionary:



      from collections import Counter

      scores = [["win","lose","win"],["win","win"],["draw","win"],["lose"]]

      empty = dict.fromkeys(('win', 'lose', 'draw'), 0)

      res = [{**empty, **Counter(i)} for i in scores]

      [{'draw': 0, 'lose': 1, 'win': 2},
      {'draw': 0, 'lose': 0, 'win': 2},
      {'draw': 1, 'lose': 0, 'win': 1},
      {'draw': 0, 'lose': 1, 'win': 0}]





      share|improve this answer





















      • Copying dictionaries for each item in the list comprehension seems pretty inefficient.
        – planetp
        Nov 10 at 9:41










      • @planetp, I disagree, time complexity is the same as cycling through the ('win', 'lose', 'draw') keys one at a time.
        – jpp
        Nov 10 at 11:50













      up vote
      2
      down vote










      up vote
      2
      down vote









      Your desired result isn't valid syntax. Most likely you want a list of dictionaries.



      collections.Counter only counts values in an iterable; it does not count externally supplied keys unless you supply additional logic.



      In this case, you can use a list comprehension, combining with an empty dictionary:



      from collections import Counter

      scores = [["win","lose","win"],["win","win"],["draw","win"],["lose"]]

      empty = dict.fromkeys(('win', 'lose', 'draw'), 0)

      res = [{**empty, **Counter(i)} for i in scores]

      [{'draw': 0, 'lose': 1, 'win': 2},
      {'draw': 0, 'lose': 0, 'win': 2},
      {'draw': 1, 'lose': 0, 'win': 1},
      {'draw': 0, 'lose': 1, 'win': 0}]





      share|improve this answer












      Your desired result isn't valid syntax. Most likely you want a list of dictionaries.



      collections.Counter only counts values in an iterable; it does not count externally supplied keys unless you supply additional logic.



      In this case, you can use a list comprehension, combining with an empty dictionary:



      from collections import Counter

      scores = [["win","lose","win"],["win","win"],["draw","win"],["lose"]]

      empty = dict.fromkeys(('win', 'lose', 'draw'), 0)

      res = [{**empty, **Counter(i)} for i in scores]

      [{'draw': 0, 'lose': 1, 'win': 2},
      {'draw': 0, 'lose': 0, 'win': 2},
      {'draw': 1, 'lose': 0, 'win': 1},
      {'draw': 0, 'lose': 1, 'win': 0}]






      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Nov 9 at 13:15









      jpp

      84.3k194897




      84.3k194897












      • Copying dictionaries for each item in the list comprehension seems pretty inefficient.
        – planetp
        Nov 10 at 9:41










      • @planetp, I disagree, time complexity is the same as cycling through the ('win', 'lose', 'draw') keys one at a time.
        – jpp
        Nov 10 at 11:50


















      • Copying dictionaries for each item in the list comprehension seems pretty inefficient.
        – planetp
        Nov 10 at 9:41










      • @planetp, I disagree, time complexity is the same as cycling through the ('win', 'lose', 'draw') keys one at a time.
        – jpp
        Nov 10 at 11:50
















      Copying dictionaries for each item in the list comprehension seems pretty inefficient.
      – planetp
      Nov 10 at 9:41




      Copying dictionaries for each item in the list comprehension seems pretty inefficient.
      – planetp
      Nov 10 at 9:41












      @planetp, I disagree, time complexity is the same as cycling through the ('win', 'lose', 'draw') keys one at a time.
      – jpp
      Nov 10 at 11:50




      @planetp, I disagree, time complexity is the same as cycling through the ('win', 'lose', 'draw') keys one at a time.
      – jpp
      Nov 10 at 11:50












      up vote
      1
      down vote













      You could apply a list comprehension for every sublist from your given list.



      Also, declare your own counter function which counts the number of appearances of one item from win, lose or draw.



      scores = [["win","lose","win"],["win","win"],["draw","win"],["lose"]]
      def get_number(sublist):
      counter = {'win': 0, 'draw' : 0, 'lose': 0}
      for item in sublist:
      counter[item] += 1
      return counter

      result = [get_number(sublist) for sublist in scores]


      Output



      [{'win': 2, 'draw': 0, 'lose': 1}, 
      {'win': 2, 'draw': 0, 'lose': 0},
      {'win': 1, 'draw': 1, 'lose': 0},
      {'win': 0, 'draw': 0, 'lose': 1}]





      share|improve this answer



























        up vote
        1
        down vote













        You could apply a list comprehension for every sublist from your given list.



        Also, declare your own counter function which counts the number of appearances of one item from win, lose or draw.



        scores = [["win","lose","win"],["win","win"],["draw","win"],["lose"]]
        def get_number(sublist):
        counter = {'win': 0, 'draw' : 0, 'lose': 0}
        for item in sublist:
        counter[item] += 1
        return counter

        result = [get_number(sublist) for sublist in scores]


        Output



        [{'win': 2, 'draw': 0, 'lose': 1}, 
        {'win': 2, 'draw': 0, 'lose': 0},
        {'win': 1, 'draw': 1, 'lose': 0},
        {'win': 0, 'draw': 0, 'lose': 1}]





        share|improve this answer

























          up vote
          1
          down vote










          up vote
          1
          down vote









          You could apply a list comprehension for every sublist from your given list.



          Also, declare your own counter function which counts the number of appearances of one item from win, lose or draw.



          scores = [["win","lose","win"],["win","win"],["draw","win"],["lose"]]
          def get_number(sublist):
          counter = {'win': 0, 'draw' : 0, 'lose': 0}
          for item in sublist:
          counter[item] += 1
          return counter

          result = [get_number(sublist) for sublist in scores]


          Output



          [{'win': 2, 'draw': 0, 'lose': 1}, 
          {'win': 2, 'draw': 0, 'lose': 0},
          {'win': 1, 'draw': 1, 'lose': 0},
          {'win': 0, 'draw': 0, 'lose': 1}]





          share|improve this answer














          You could apply a list comprehension for every sublist from your given list.



          Also, declare your own counter function which counts the number of appearances of one item from win, lose or draw.



          scores = [["win","lose","win"],["win","win"],["draw","win"],["lose"]]
          def get_number(sublist):
          counter = {'win': 0, 'draw' : 0, 'lose': 0}
          for item in sublist:
          counter[item] += 1
          return counter

          result = [get_number(sublist) for sublist in scores]


          Output



          [{'win': 2, 'draw': 0, 'lose': 1}, 
          {'win': 2, 'draw': 0, 'lose': 0},
          {'win': 1, 'draw': 1, 'lose': 0},
          {'win': 0, 'draw': 0, 'lose': 1}]






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 9 at 13:22

























          answered Nov 9 at 13:15









          Mihai Alexandru-Ionut

          29k63467




          29k63467






















              up vote
              1
              down vote














              Can I do this using a dictionary?




              You can use collections.Counter, which is a subclass of dict for counting hashable objects:



              >>> from collections import Counter
              >>> scores = [['win', 'lose', 'win'], ['win', 'win'], ['draw', 'win'], ['lose']]
              >>> counts = [Counter(score) for score in scores]
              >>> counts
              [Counter({'win': 2, 'lose': 1}), Counter({'win': 2}), Counter({'draw': 1, 'win': 1}), Counter({'lose': 1})]


              To add zero counts for missing keys you can use an additional loop:



              >>> for c in counts:
              ... for k in ('win', 'lose', 'draw'):
              ... c[k] = c.get(k, 0)
              ...
              >>> counts
              [Counter({'win': 2, 'lose': 1, 'draw': 0}), Counter({'win': 2, 'lose': 0, 'draw': 0}), Counter({'draw': 1, 'win': 1, 'lose': 0}), Counter({'lose': 1, 'win': 0, 'draw': 0})]


              Alternatively, you could wrap the counters with collections.defaultdict:



              >>> counts = [defaultdict(int, Counter(score)) for score in scores]
              >>> counts
              [defaultdict(<class 'int'>, {'win': 2, 'lose': 1}), defaultdict(<class 'int'>, {'win': 2}), defaultdict(<class 'int'>, {'draw': 1, 'win': 1}), defaultdict(<class 'int'>, {'lose': 1})]
              >>> counts[0]['draw']
              0





              share|improve this answer



























                up vote
                1
                down vote














                Can I do this using a dictionary?




                You can use collections.Counter, which is a subclass of dict for counting hashable objects:



                >>> from collections import Counter
                >>> scores = [['win', 'lose', 'win'], ['win', 'win'], ['draw', 'win'], ['lose']]
                >>> counts = [Counter(score) for score in scores]
                >>> counts
                [Counter({'win': 2, 'lose': 1}), Counter({'win': 2}), Counter({'draw': 1, 'win': 1}), Counter({'lose': 1})]


                To add zero counts for missing keys you can use an additional loop:



                >>> for c in counts:
                ... for k in ('win', 'lose', 'draw'):
                ... c[k] = c.get(k, 0)
                ...
                >>> counts
                [Counter({'win': 2, 'lose': 1, 'draw': 0}), Counter({'win': 2, 'lose': 0, 'draw': 0}), Counter({'draw': 1, 'win': 1, 'lose': 0}), Counter({'lose': 1, 'win': 0, 'draw': 0})]


                Alternatively, you could wrap the counters with collections.defaultdict:



                >>> counts = [defaultdict(int, Counter(score)) for score in scores]
                >>> counts
                [defaultdict(<class 'int'>, {'win': 2, 'lose': 1}), defaultdict(<class 'int'>, {'win': 2}), defaultdict(<class 'int'>, {'draw': 1, 'win': 1}), defaultdict(<class 'int'>, {'lose': 1})]
                >>> counts[0]['draw']
                0





                share|improve this answer

























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote










                  Can I do this using a dictionary?




                  You can use collections.Counter, which is a subclass of dict for counting hashable objects:



                  >>> from collections import Counter
                  >>> scores = [['win', 'lose', 'win'], ['win', 'win'], ['draw', 'win'], ['lose']]
                  >>> counts = [Counter(score) for score in scores]
                  >>> counts
                  [Counter({'win': 2, 'lose': 1}), Counter({'win': 2}), Counter({'draw': 1, 'win': 1}), Counter({'lose': 1})]


                  To add zero counts for missing keys you can use an additional loop:



                  >>> for c in counts:
                  ... for k in ('win', 'lose', 'draw'):
                  ... c[k] = c.get(k, 0)
                  ...
                  >>> counts
                  [Counter({'win': 2, 'lose': 1, 'draw': 0}), Counter({'win': 2, 'lose': 0, 'draw': 0}), Counter({'draw': 1, 'win': 1, 'lose': 0}), Counter({'lose': 1, 'win': 0, 'draw': 0})]


                  Alternatively, you could wrap the counters with collections.defaultdict:



                  >>> counts = [defaultdict(int, Counter(score)) for score in scores]
                  >>> counts
                  [defaultdict(<class 'int'>, {'win': 2, 'lose': 1}), defaultdict(<class 'int'>, {'win': 2}), defaultdict(<class 'int'>, {'draw': 1, 'win': 1}), defaultdict(<class 'int'>, {'lose': 1})]
                  >>> counts[0]['draw']
                  0





                  share|improve this answer















                  Can I do this using a dictionary?




                  You can use collections.Counter, which is a subclass of dict for counting hashable objects:



                  >>> from collections import Counter
                  >>> scores = [['win', 'lose', 'win'], ['win', 'win'], ['draw', 'win'], ['lose']]
                  >>> counts = [Counter(score) for score in scores]
                  >>> counts
                  [Counter({'win': 2, 'lose': 1}), Counter({'win': 2}), Counter({'draw': 1, 'win': 1}), Counter({'lose': 1})]


                  To add zero counts for missing keys you can use an additional loop:



                  >>> for c in counts:
                  ... for k in ('win', 'lose', 'draw'):
                  ... c[k] = c.get(k, 0)
                  ...
                  >>> counts
                  [Counter({'win': 2, 'lose': 1, 'draw': 0}), Counter({'win': 2, 'lose': 0, 'draw': 0}), Counter({'draw': 1, 'win': 1, 'lose': 0}), Counter({'lose': 1, 'win': 0, 'draw': 0})]


                  Alternatively, you could wrap the counters with collections.defaultdict:



                  >>> counts = [defaultdict(int, Counter(score)) for score in scores]
                  >>> counts
                  [defaultdict(<class 'int'>, {'win': 2, 'lose': 1}), defaultdict(<class 'int'>, {'win': 2}), defaultdict(<class 'int'>, {'draw': 1, 'win': 1}), defaultdict(<class 'int'>, {'lose': 1})]
                  >>> counts[0]['draw']
                  0






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 10 at 9:15

























                  answered Nov 9 at 13:14









                  Eugene Yarmash

                  81.8k22172257




                  81.8k22172257






























                       

                      draft saved


                      draft discarded



















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53226311%2fcount-the-number-of-times-an-item-occurs-in-each-nested-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

                      Landwehr

                      Reims

                      Schenkenzell