I've been dabbling with IronPython for the past two weeks now. For me it compares quite favourably to the experience I had driving in this country. I used to drive a manual transmission car back in India and I used C# primarily. When I came to the US two weeks back I started driving an automatic transmission vehicle and I started using python. Initially the car felt weird - it was like driving some toy car, every time I'd slow down and my hands used to reach for the gears and my legs kept going towards the non-existent clutch. Similarly, I'd constantly put semicolons and braces everywhere, add type information all over the place and new up everything, indent the code wrongly. Now I'm getting used to the automatic and python and probably somwhere down the line, it might make me lazy enough to start disliking the manuals and static languages. (Although I dont see that happening with C# seeing as how I'm still going to be doing a lot of coding in C#).

Anyway I thought, I'll come up with the list of things I find cool and/or useful (not necessarily the same) in python.

Lists and List Comprehension

Being a fan of LINQ this was one of the first things about the language that interested me. I think the creation and maintenance of lists in python is very light on syntax and though it might not be as powerful as LINQ it does what it does well.

List comprehension is an easy way of constructing new lists from existing ones. To get a list of all IronPython process Ids

procIds = [ x.Id for x in Process.GetProcesses() if x.ProcessName == "ipy"]

Or say you have some functions and parameters and you want to call them in a cross-productish way:

results = [ [y(x) for y in funcs] for x in params ]

It also supports filter, map, reduce (equivalent of where, select and aggregate in C#) and the usual suspects like sorted, reversed etc..

Sequence packing/unpacking:

Sequences (lists, tuples etc) can be constructed from loose elements or can be disintegrated into individual variables. For example this can be done:

t = 3, 30, 300
a,b,c = t

A tuple t is constructed from the loose values and then it is unpacked into three loose variables a, b and c. This enables a bunch of cool scenarios. For examples I can now return multiple values from a function and assign them intuitively:

def f():
    return "a", 3
a, b = f()

The return value of that function was just a tuple packed and unpacked for you. This also lets you do this to swap numbers which I find pretty cool:

a, b = b, a

A related feature is argument unpacking. You can pass a tuple to a function and ask it to unpack the tuple and distribute it to the parameters. All you need to do this put a * in front of the tuple while passing it. For example:

def Multiply(a, b):
    return a*b;
params = [ (4,5), (4, "thisrepeats!") ]
results = [ Multiply(*p) for p in params ]

You can also pass in a dictionary and assign specific values.

Multiply( **{'a':2, 'b':"c"})

Else clause

for loops (or try/catch blocks) can have else clauses: I dont have to have a flag now checking to see if the loop has exited on a break or otherwise:

for item in listToSearch:
    if item == theOneImLookingFor:
        print "Found it"
        break
else:  #loop fell through
    print "Sorry, its not there"
There's more but those probably warrant another post.