18

Python 3.3, a dictionary with key-value pairs in this form.

d = {'T1': ['eggs', 'bacon', 'sausage']}

The values are lists of variable length, and I need to iterate over the list items. This works:

count = 0
for l in d.values():
   for i in l: count += 1

But it's ugly. There must be a more Pythonic way, but I can't seem to find it.

len(d.values()) 

produces 1. It's 1 list (DUH). Attempts with Counter from here give 'unhashable type' errors.

Community
  • 1
  • 1
RolfBly
  • 3,612
  • 5
  • 32
  • 46

5 Answers5

52

Use sum() and the lengths of each of the dictionary values:

count = sum(len(v) for v in d.itervalues())

If you are using Python 3, then just use d.values().

Quick demo with your input sample and one of mine:

>>> d = {'T1': ['eggs', 'bacon', 'sausage']}
>>> sum(len(v) for v in d.itervalues())
3
>>> d = {'T1': ['eggs', 'bacon', 'sausage'], 'T2': ['spam', 'ham', 'monty', 'python']}
>>> sum(len(v) for v in d.itervalues())
7

A Counter won't help you much here, you are not creating a count per entry, you are calculating the total length of all your values.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
16
>>> d = {'T1': ['eggs', 'bacon', 'sausage'], 'T2': ['spam', 'ham', 'monty', 'python']}
>>> sum(map(len, d.values()))
7
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
0

Doing my homework on Treehouse I came up with this. It can be made simpler by one step at least (that I know of), but it might be easier for beginners (like myself) to onderstand this version.

dict = {'T1': ['eggs', 'bacon', 'sausage'], 'T2': ['bread', 'butter', 'tosti']}

total = 0

for value in dict:
    value_list = dict[value]
    count = len(value_list)
    total += count

print(total)
Rik Schoonbeek
  • 3,908
  • 2
  • 25
  • 43
0

For me the simplest way is:

winners = {1931: ['Norman Taurog'], 1932: ['Frank Borzage'], 1933: ['Frank Lloyd'], 1934: ['Frank Capra']}

win_count_dict = {}

for k,v in winners.items():
    for winner in v:
        if winner not in win_count_dict:
            win_count_dict[winner]=1
        else:
            win_count_dict[winner]+=1


print("win_count_dict = {}".format(win_count_dict))
  • You are reinventing `defaultdict(int)` – tripleee Dec 16 '20 at 07:10
  • Probably because you didn't know it exists? The standard library offers a component in the `collections` module which spares you from having to check whether the key is already defined; [documentation.](https://docs.python.org/3.8/library/collections.html#collections.defaultdict) – tripleee Dec 16 '20 at 07:19
  • haha wow! seems way easier and simple lol loved it! thanks – mluanastevens Dec 16 '20 at 07:23
-1

I was looking for an answer to this when I found this topic untill I realized I already had something in my code to use this for. This is what I came up with:

count = 0

for key, values in dictionary.items():
        count = len(values)

If you want to save the count for every dictionary item you could create a new dictionary to save the count for each key.

count = {}

for key, values in dictionary.items():
        count[key] = len(values)

I couldn't exactly find from which version this method is available but I think .items method is only available in Python 3.

Jeffrey
  • 105
  • 1
  • 1
  • 8