performance improved by using operator.itemgetter and cache for mode