Sayth Renshaw wrote: > Hi > > I have got this dictionary comprehension and it works but how can I do it > better?
List comprehensions (that's what you have) are nice, but overused. > from collections import Counter > > def find_it(seq): > counts = dict(Counter(seq)) There is no need to convert Counter to dict. > a = [(k, v) for k,v in counts.items() if v % 3 == 0] > return a[0][0] > > test_seq = [20,1,-1,2,-2,3,3,5,5,1,2,4,20,4,-1,-2,5] > > so this returns 5 which is great and the point of the problem I was doing. > > Can also do it like this > def find_it(seq): > counts = dict(Counter(seq)) > a = [(k) for k,v in counts.items() if v % 3 == 0] > return a[0] > > But the given problem states there will always only be one number > appearing an odd number of times given that is there a neater way to get > the answer? If you mean there is only one number satisfying the v % 3 == 0 condition then there is no need to go through the whole sequence. The clearest way to express that is for k, v in counts.items(): if v % 3 == 0: return k raise ValueError but it = (k for k, v in counts.items() if v % 3 == 0) try: return next(it) except StopIteration: pass raise ValueError is also possible. The parens (...) instead of [...] make "it" generator expression which is evaluated lazily. Both alternatives shown above ensure that at least one value satisfies the condition "number of occurencies divides by three without rest". If you want to play it safe and verify that there is exactly one such key you may keep the listcomp, preferably that from your second implementation. a = [...] if len(a) != 1: raise ValueError return a[0] or [result] = a # will raise a ValueError if len(a) != 1 The complete code: >>> from collections import Counter >>> def find_it(seq): ... [result] = [k for k, v in Counter(seq).items() if v % 3 == 0] ... return result ... >>> test_seq = [20,1,-1,2,-2,3,3,5,5,1,2,4,20,4,-1,-2,5] >>> find_it(test_seq) 5 -- https://mail.python.org/mailman/listinfo/python-list