I am sure this is silly, but I simply cannot get around it. I have a dictionary, like this, with unequal number of values for each key:
'John greased ': ['axle', 'wheel', 'wheels', 'wheel', 'engine', ''], 'Paul alleged ': ['truth', 'crime', 'facts', 'infidelity', 'incident', ''], 'Tracy freed ': ['animals', 'fish', 'slaves', 'slaves', 'slaves', 'pizza'], 'Lisa plowed ': ['field', 'field', '', '', '', ''], I want to know how many values there are for each key, not each unique value but how many tokens there are per key, repeated or not. So I would have a result like:
John greased 5 Paul alleged 5 Tracy freed 6 Lisa plowed 2 I was trying to use this to work it out using the code bellow:
for key, value in sorted(result.items()): print(key, len(value)) But because of the missing values all the lengths turn out to be the same. Any ideas on how to solve this or where to find it out? Thanks a lot for any help.
4 Answers
One way to solve this, is by changing your last line:
print(key, len([item for item in value if item])) So your complete code:
ITEMS = { 'John greased ': ['axle', 'wheel', 'wheels', 'wheel', 'engine', ''], 'Paul alleged ': ['truth', 'crime', 'facts', 'infidelity', 'incident', ''], 'Tracy freed ': ['animals', 'fish', 'slaves', 'slaves', 'slaves', 'pizza'], 'Lisa plowed ': ['field', 'field', '', '', '', ''], } for key, value in ITEMS.items(): #print value print(key, len([item for item in value if item])) You can also use filter with bool:
print(key, len(filter(bool, value))) So, the loop:
for key, value in ITEMS.items(): #print value print(key, len(filter(bool, value))) You need to apply list over filter like so print(key, len(list(filter(bool, value)))) in Python 3.
Use filter with None, it filters out all falsy values from the iterable passed to it.
In Python3 filter returns an iterator so you should call list() on it.:
>>> lis = ['field', 'field', '', '', '', ''] >>> list(filter(None, lis)) ['field', 'field'] >>> len(list(filter(None, lis))) 2 Code:
>>> my_dict = { 'John greased ': ['axle', 'wheel', 'wheels', 'wheel', 'engine', ''], 'Paul alleged ': ['truth', 'crime', 'facts', 'infidelity', 'incident', ''], 'Tracy freed ': ['animals', 'fish', 'slaves', 'slaves', 'slaves', 'pizza'], 'Lisa plowed ': ['field', 'field', '', '', '', ''], } for k,v in my_dict.items(): print (k, len(list(filter(None, v)))) ... Paul alleged 5 Lisa plowed 2 John greased 5 Tracy freed 6 Timing comparision between filter(None,..) and list comprehension:
>>> lis = ['field', 'field', '', '', '', '']*100 >>> %timeit list(filter(None, lis)) 10000 loops, best of 3: 22.2 us per loop >>> %timeit [item for item in lis if item] 10000 loops, best of 3: 53.1 us per loop >>> lis = ['field', 'field', '', '', '', '']*10000 >>> %timeit list(filter(None, lis)) 100 loops, best of 3: 2.36 ms per loop >>> %timeit [item for item in lis if item] 100 loops, best of 3: 5.22 ms per loop 6Look at this:
>>> dct = {'John greased ': ['axle', 'wheel', 'wheels', 'wheel', 'engine', ''], ... 'Paul alleged ': ['truth', 'crime', 'facts', 'infidelity', 'incident', ''], ... 'Tracy freed ': ['animals', 'fish', 'slaves', 'slaves', 'slaves', 'pizza'], ... 'Lisa plowed ': ['field', 'field', '', '', '', '']} >>> >>> {k:sum(1 for x in v if x) for k,v in dct.items()} {'Paul alleged ': 5, 'Lisa plowed ': 2, 'John greased ': 5, 'Tracy freed ': 6} >>> >>> for key,value in dct.items(): ... print(key, sum(1 for v in value if v)) ... Paul alleged 5 Lisa plowed 2 John greased 5 Tracy freed 6 >>> 0data = { 'John greased ': ['axle', 'wheel', 'wheels', 'wheel', 'engine', ''], 'Paul alleged ': ['truth', 'crime', 'facts', 'infidelity', 'incident', ''], 'Tracy freed ': ['animals', 'fish', 'slaves', 'slaves', 'slaves', 'pizza'], 'Lisa plowed ': ['field', 'field', '', '', '', ''] } for each in data: i = 0 print each for item in data[each]: if len(item) > 0: i =i +1 print i