sara
sara

Reputation: 1

Python dictionary for and if loop

I'm very new to python. This question might be very simple. I have two lists as below;

Mobile=  ('M1','M1','M1','M1','M1','M1','M1','M2','M2','M2','M2','M2','M2','M2')
Test=('call','call','sms','sms','mms','call','call','mms','mms','sms','sms','voltecall','voltecall','voltecall')

I want to write a loop to count how many times each Test item is done for each value in Mobile. For example I want the code to tell me 'M1' had Four 'call' scenarios, Two 'sms' and one 'mms'. I thought I could do this in dictionary so I created a tot variable to use as a key in dictionary and created the dictionary (as below) but i'm not sure how to use for and if statements to do what I want. The code I wrote below is not giving the correct answer. It just returns zero.

Mobile=  ('M1','M1','M1','M1','M1','M1','M1','M2','M2','M2','M2','M2','M2','M2')
Test=('call','call','sms','sms','mms','call','call','mms','mms','sms','sms','voltecall','voltecall','voltecall')
tot=(1,2,3,4,5,6,7,8,9,10,11,12,13,14)

a_dict=dict(zip(tot,zip(Mobile,Test)))

for k, v in a_dict.iteritems():
    if (k==Mobile[1] and v==Test[1]):
        countM1Test1+=1

Upvotes: 0

Views: 77

Answers (2)

akuiper
akuiper

Reputation: 214987

You can use defaultdict with Counter as follows:

from collections import defaultdict, Counter
​
count = defaultdict(Counter)
for m, t in zip(Mobile, Test):
    count[m].update({t: 1})

count
# defaultdict(collections.Counter,
#             {'M1': Counter({'call': 4, 'mms': 1, 'sms': 2}),
#              'M2': Counter({'mms': 2, 'sms': 2, 'voltecall': 3})})

If you want a list of tuples, you can easily extract the tuple from the dictionary count above with a list comprehension:

[(k, a, c) for k, v in count.items() for a, c in v.items()]

# [('M1', 'mms', 1),
#  ('M1', 'sms', 2),
#  ('M1', 'call', 4),
#  ('M2', 'mms', 2),
#  ('M2', 'sms', 2),
#  ('M2', 'voltecall', 3)]

Update:

If you have three lists, you can make a nested defaultdict:

Mobile=  ('M1','M1','M1','M1','M1','M1','M1','M2','M2','M2','M2','M2','M2','M2')
Test=('call','call','sms','sms','mms','call','call','mms','mms','sms','sms','voltecall','voltecall','voltecall')
Response = ('error', 'success', 'skip', 'error', 'success', 'skip', 'error', 'success', 'skip', 'error', 'success', 'skip', 'error', 'success')

from collections import defaultdict, Counter

count = defaultdict(lambda : defaultdict(Counter))
for m, t, r in zip(Mobile, Test, Response):
    count[m][t].update({r: 1})

Note: If you have even more, I suggest you take a look at pandas library, it makes this type of grouped operation kind of more straight forward.

Upvotes: 2

Owlette
Owlette

Reputation: 71

from collections import Counter
pairs = zip(*(Mobile, Test))
c = Counter(pairs)
print c.items()

output:

[(('M1', 'sms'), 2), (('M2', 'voltecall'), 3), (('M1', 'call'), 4), (('M2', 'mms'), 2), (('M2', 'sms'), 2), (('M1', 'mms'), 1)]

Upvotes: 0

Related Questions