Saurav Chirania wrote: > I really like that python's sort method accepts a key function as a > parameter which can be used to specify how elements should be compared. > > Similarly, we could have a "key" argument which specifies how elements > should be counted. Let's say we have a list of a million students. I would > like to do something like: > c = Counter(students, key = lambda student: student.marks) > > which would return a Counter which maps marks to the number of students > with that marks. Let's say 29 students in the list had scored 100 marks, > so one entry in the counter would be key=100, val=29. > > So, why doesn't Counter's constructor support this argument? Are there > other pythonic ways to do this?
Yes, as the counter won't store the original student there is no advantage over the direct translation of your code Counter(map(lambda: student.marks, students)) or the more elegant variant with a generator expression Counter(student.marks for student in students) Functions like max() which do offer a key arg are a bit different as max(student.marks for student in students) returns the highest marks whereas max(students, key=lambda: student.marks) returns the student with the highest marks. To spell the latter without a key arg would require something more complicated like max((s.marks, i, s) for i, s in enumerate(students))[-1] If you need to count the marks while remembering the students you would use a dict or defaultdict instead of a counter, d = defaultdict(list) for s in students: d[s.marks] = s or, if the students are sorted by marks, itertools.groupby(). -- https://mail.python.org/mailman/listinfo/python-list