List comprehensions (LCs) Note: Resurrected from another one of my places.
Basic LC forms |
---|
Traditional for loop c = [] for i in range(20): if (i > 5) and (i < 10): c.append(i**2) The smokin' cryptic one-liner a = [i**2 for i in range(20) if i > 5 and i < 10] The stacked, commented multi-liner b = [i**2 # do this for i in range(20) # using these if (i > 5) and # where this and (i < 10) # this is good ] |
Condition checking with numbers and conditions |
---|
Again, the three methods, but this time the condition checking is done upfront with an if-else clause. This query is simply checking to see whether elements in a list are all numbers. If True, return the number, if False, assign -999. nums = [0,1,None,3,None,5,6] # the list of numbers to check conventional approach >>> good = [] >>> for val in nums: ... if isinstance(val, (int,float)): ... good.append(val) ... else: ... good.append(-999) ... basic list comprehension >>> good = [ val if isinstance(val,(int,float)) else -999 for val in nums] >>> stacked list comprehension >>> good = [ ... val # return the value ... if isinstance(val,(int,float)) # if this is true ... else -999 # return this otherwise ... for val in nums # for each value in the list ... ] in all cases >>> good [0, 1, -999, 3, -999, 5, 6] |
More on condition checking |
---|
Some times you want to perform an operation given certain conditions. In the example below, a check is made to ensure that "b" is not zero to avoid division by zero. If it is zero, then an alternate value is supplied. There are two variants of the LC shown and the results are compared as a final step...examine closely. outer = [1,2] inner = [2,0,4] c = [[a, b, a*b, a*b/1.0] # divide 2 numbers (outer/inner) if b # if != 0 (0 is a boolean False) else [a,b,a*b,"N/A"] # if equal to zero, do this for a in outer # for each value in the outer list for b in inner # for each value in the inner list ] for val in c: # val[0],val[1],val[2])) print("a({}), b({}), a*b({}) a/b({})".format(*val )) d = [[[a,b,a*b,"N/A"], # do if False [a,b,a*b,a*b/1.0]][b!=0] # do if True ... then slice for a in outer for b in inner ] print("d == c??? {}".format(d==c)) a(1), b(2), a*b(2) a/b(2.0) a(1), b(0), a*b(0) a/b(N/A) a(1), b(4), a*b(4) a/b(4.0) a(2), b(2), a*b(4) a/b(4.0) a(2), b(0), a*b(0) a/b(N/A) a(2), b(4), a*b(8) a/b(8.0) d == c??? True |
The examples shown here are just the beginning. The reader should be aware that there are dictionary and set comprehensions as well. This topic will also serve as a gentle introduction to generators.
If you would like to see other examples, please send me a note.
Additions |
---|
What is the difference between a list comprehension and a set comprehension. Basically, a process step is the only thing sometimes. As seen below, the set_comp results are completed during the query, whereas the list_comp results in line 04 still need to have a set() operation applied after the fact, should a set truly be required. >>> a = [1,2,1,1,2,3,3,2,1,1,1,2,3,4,9,8,1,7,7,7,7,7] >>> list_comp = [ i for i in a if i >3 ] >>> set_comp = { i for i in a if i > 3 } >>> list_comp [4, 9, 8, 7, 7, 7, 7, 7] >>> set_comp set([8, 9, 4, 7]) >>> a = [5,6,5,6,5,6,5,6,5,6,4,4] >>> b = [5,6] >>> lc = [ x*y for x in a for y in b] >>> sc = { x*y for x in a for y in b } >>> lc [25, 30, 30, 36, 25, 30, 30, 36, 25, 30, 30, 36, 25, 30, 30, 36, 25, 30, 30, 36, 20, 24, 20, 24] >>> sc {24, 25, 36, 20, 30} >>> |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.