Thursday, November 6, 2008

k_minima in Python

I am really excited about the Real World Haskell book that is coming out soon. I went through the slides from Bryan O'Sullivan's presentation. He describes implementing k_minima in Haskell. I wanted to give a go at implementing his Haskellish k_minima in Python using itertools. Here is what I came up with.


#! /usr/bin/env python

from itertools import *

DEBUG = False

def debug(*msgs):
if DEBUG: print 'DEBUG:', msgs

def take(k, elements):
"""
Extracts the first k elements from a list
"""
if k > 0:
for index, element in izip(count(), elements):
debug('take', index, element)
yield element
if index == k - 1: break

def sort(elements):
"""
Sorts a list
"""
remaining = elements[:]
while remaining:
minimum = min(remaining)
remaining.remove(minimum)
debug('sort', minimum, remaining)
yield minimum

def k_minima(k, elements):
"""
Find the k least elements in a list
"""
for element in take(k, sort(elements)):
yield element

def main(k, elements):
debug('main', k, elements)
print list(k_minima(k, elements))

if __name__ == '__main__':
import sys
if len(sys.argv) > 2:
elements = [int(arg) for arg in sys.argv[1:]]
main(elements[0], elements[1:])
else:
print 'Useage: k_minima.py k element [element] ...'



Here is an example of running the program.


py$ ./k_minima.py 12 42 37 42 11 599 33 499 44 499 488 499 499 488347 448 4 588 7 85 48 59 84
[4, 7, 11, 33, 37, 42, 42, 44, 48, 59, 84, 85]
py$

No comments: