How to count the repetition of the elements in a list python, django

4.9k views Asked by At

I have a django app, I am using django-taggit for my blog.

Now I have a list of elements (In fact objects) that I got from database in one of my view as below

tags = [<Tag: some>, <Tag: here>, <Tag: tags>, <Tag: some>, <Tag: created>, <Tag: here>, <Tag: tags>]

Now how to find the count of each element in the list and return a list of tuples as below

result should be as below

[(<Tag: some>,2),(<Tag: here>,2),(<Tag: created>,1),(<Tag: tags>,2)]

so that I can use them in template by looping it something like below

view

def display_list_of_tags(request):
    tags = [<Tag: some>, <Tag: here>, <Tag: tags>, <Tag: some>, <Tag: created>, <Tag: here>, <Tag: tags>]
    # After doing some operation on above list as indicated above
    tags_with_count =  [(<Tag: some>,2),(<Tag: here>,2),(<Tag: created>,1),(<Tag: tags>,2)]
    return HttpResponse('some_template.html',dict(tags_with_count:tags_with_count))

template

{% for tag_obj in tags_with_count %}
   <a href="{% url 'tag_detail' tag_obj %}">{{tag_obj}}</a> <span>count:{{tags_with_count[tag_obj]}}</span>
{% endfor %}

so as described above how to count the occurences of each element in the list? The process should be ultimately fast, because I may have hundreds of tags in the tagging application right?

If the list contains only strings as elements, we could use something like from collections import counter and calculate the count, but how do do in the above case ?

All my intention is to count the occurrences and print them in the template like tag object and occurrences,

So I am searching for a fast and efficient way to perform above functionality?

Edit:

So I got the required answer from and I am sending the result to template by converting the resultant list of tuples to dictionary as below

{<Tag: created>: 1, <Tag: some>: 2, <Tag: here>: 2, <Tag: tags>: 2}

and tried to print the above dictionary by looping it in the format like

{% for tag_obj in tags_with_count %}
       <a href="{% url 'tag_detail' tag_obj %}">{{tag_obj}}</a> <span>count:{{tags_with_count[tag_obj]}}</span>
    {% endfor %}

But its displaying the below error

TemplateSyntaxError: Could not parse the remainder: '[tag_obj]' from 'tags_with_count[tag_obj]'

So how to display the dictionary in the django templates by like key and value?

Done we can change the above template looping as below

{% for tag_obj, count in tags_with_count.iteritems %}
3

There are 3 answers

0
Gill Bates On BEST ANSWER

Try Python's Counter:

from collections import Counter

l =  ['some', 'here', 'tags', 'some', 'created', 'here', 'tags']
print(Counter(l).items())

Output:

[('created', 1), ('some', 2), ('here', 2), ('tags', 2)]
0
Marcin Fabrykowski On

Try something like:

x = ['raz', 'dwa', 'raz', 'trzy', 'dwa', 'raz', 'trzy', 'cztery']
wynik = {}
for i in x:
    if i in wynik:
         wynik[i] += 1
    else:
         wynik[i] = 1
print wynik

{'cztery': 1, 'dwa': 2, 'raz': 3, 'trzy': 2}

and, if you need:

import operator
wynik_sorted = sorted(wynik.iteritems(), key=operator.itemgetter(1), reverse=True)

print wynik_sorted
[('raz', 3), ('dwa', 2), ('trzy', 2), ('cztery', 1)]
2
Emmett Butler On

The count and set functions look like they'd be of use here.

>>> l = ["i", "i", "am", "am", "am", "test"]
>>> list(set([(a, l.count(a)) for a in l]))
[('test', 1), ('i', 2), ('am', 3)]

l.count() provides the number of occurrences of the given item in the list. set() turns the list into a set (an unordered collection containing no duplicate items) and then list converts that set back to the proper type.

Since you're dealing with Tag objects, it's possible that you'd need to use some method to get their string representations (although I can't find documentation on their interface). Maybe something like this:

>>> l = [a.text for a in l]
>>> list(set([(a, l.count(a)) for a in l]))