Statically Typed

because Hindley-Milner rocks

Scala zipWithIndex for Pythonistas


Python is a wonderful language.  I use it for scripting all the time.  Hell, I use it for prototyping things too!  I love that REPL.  Using it I’ve had many “Eureka!” moments.  I think the biggest moment was discovering the true power of for comprehensions followed up by generators or as I like to call them, lazy eval for comprehensions.  Scala has for comprehensions but they’ve also got some nifty built in functionality that avoids the need to write for comprehensions.

A good example is Scala’s zipWithIndex on its List data structure.  Here’s some Python code (tagged as a “hidden feature” of Python, pfft!) which creates a list of index-value tuples:

tupleList = [ (index,item) for (index,item) in enumerate( myList ) ]
tupleList = list( enumerate( myList ) ) #Rob Smallshire's much better version

It’s short enough to be a one liner.  Here’s what it looks like in Scala:

val tupleList = myList zipWithIndex

Not only is that less complicated to read but it’s also much more descriptive with it’s intent.  As an added bonus it doesn’t force the programmer to repeat themselves, a la (index,item) twice and After Rob pointed out in the comments below a much more concise and to the point version I’ve had to retract what I said previously.  I’ll leave it up for everyone to see since I’m not right all the time.  However, I will continue to say that zipWithIndex probably won’t show up in some “hidden feature” posting about Scala.  Better yet, tell me which one you’d rather type when When converting between a list and a map:

myMap = dict( [ (index,item) for (index,item) in enumerate( myList ) ] )
myMap = dict( enumerate( myList ) ) #Rob Smallshire's version

or and the Scala version:

val myMap = Map( myList zipWithIndex: _* )

I’m not saying Scala is a better language than Python, in many ways it’s not.  Both have their uses.  Besides, I’d actually use a generator (Python’s enumerate is a generator, thanks Rob)  instead of the for comprehension in Python and a Stream in Scala.  Why?  They don’t create a temporary list which is much more efficient.  I’ll have to revisit this post again some day soon.

If you’re wondering, I’m using Eclipse with the updated Scala 2.7.7 plug-in.  It’s not as snazzy as the NetBeans but I do like the coloring scheme more.

Advertisements

3 comments on “Scala zipWithIndex for Pythonistas

  1. Rob Smallshire
    April 4, 2010

    The list comprehension is not required in either of your Python examples because enumerate() is itself a generator. In the first example you can force evaluation of the values returned by the enumerator by constructing a list:

    tupleList = list(enumerate( myList ))

    which is effectively what your list comprehension does.

    The second example is similarly simple,

    myMap = dict(enumerate( myList ))

    I would argue that both are shorter and easier to read that their Scala equivalents. The repetition of (index,item) you mention in your examples is the indicator that the list comprehensions aren’t needed – this is true any time you have the same expression on either side of the ‘for’ in a list or generator comprehension.

    • owreese
      April 4, 2010

      I had merely copied that from the Stack Overflow entry in “hidden features of Python” without giving it any thought. Your version is much better.

      • Rob Smallshire
        April 5, 2010

        I’m not right all of the time either 😉 The final statement of my comment above isn’t correct. In fact, list comprehensions may have the same expression on either side of the ‘for’ keyword where they are used for filtering. For example, to select all of the elements with a length greater than one you can do [elem for elem in li if len(elem) > 1].

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Information

This entry was posted on March 20, 2010 by in Python, Scala.
%d bloggers like this: