Marzipan
Marzipan

Reputation: 13

Counting repeating dictionaries, then appending a count key and it's value

I have a list of dictionaries:

flist = [
     {'ext' : '.txt', 'name' : 'file1'},
     {'ext' : '.png', 'name' : 'picture1'},
     {'ext' : '.txt', 'name' : 'file1'},
     {'ext' : '.py', 'name' : 'script'},
    ]

I want to create a new list which has a count of how many times the item showed up in the first list.

summary = []

for item in flist:
     if item not in summary:
            item['count'] = 1
            summary.append(item)
     else:
            item['count'] += 1

for i in summary:
     print i

I want the output list to look like this:

{'count': 2, 'ext': '.txt', 'name': 'file1'}
{'count': 1, 'ext': '.png', 'name': 'picture1'}
{'count': 1, 'ext': '.py', 'name': 'script'}

But what ends up happening is I get all 4 items, with "count: 1". I assume because it's adding count : 1 the first time, which makes that dict unique.

{'count': 1, 'ext': '.txt', 'name': 'file1'}
{'count': 1, 'ext': '.png', 'name': 'picture1'}
{'count': 1, 'ext': '.txt', 'name': 'file1'}
{'count': 1, 'ext': '.py', 'name': 'script'}

Upvotes: 1

Views: 55

Answers (3)

stamaimer
stamaimer

Reputation: 6475

You can use groupby after sort the original list.

l = sorted(flist, key=lambda item: item["ext"])

summary = []

for key, value in groupby(l):
    key.update({"count": len(list(value))})
    summary.append(key)

Upvotes: 0

Rahul K P
Rahul K P

Reputation: 16081

You can do like this with groupby,

In [76]: from itertools import groupby
In [77]: data = []
In [78]: for g,l in groupby(sorted(flist)):
    ...:     g.update({'count':len(list(l))})
    ...:     data.append(g)
    ...:     

In [79]: print data
Out[79]: 
[{'count': 1, 'ext': '.png', 'name': 'picture1'},
 {'count': 1, 'ext': '.py', 'name': 'script'},
 {'count': 2, 'ext': '.txt', 'name': 'file1'}]

Upvotes: 2

OneCricketeer
OneCricketeer

Reputation: 191725

Two problems.

1) item in summary - You are editing the item from flist with a count, therefore the original item no longer exists.

2) You only append the initial value, not the sum

item['count'] = 1
summary.append(item)

You might be interested in the Counter object

from collections import Counter, namedtuple
File = namedtuple('File', ['name', 'ext'])

flist = [
  File('file1', '.txt'),
  File('picture1', 'png'),
  File('file1', '.txt'),
  File('script', '.py')
  ]

c = Counter()
for f in flist:
  c[f] += 1

for f, count in c.items():
  print(count, f)

Output

2 File(name='file1', ext='.txt')
1 File(name='picture1', ext='png')
1 File(name='script', ext='.py')

Upvotes: 0

Related Questions