A list comprehension derives a new list from an existing list, and was adopted by Python from the Haskell language. This snippet tries to explain the development of list comprehension and shows a number of uses, including nested list comprehension. The benefits are simplicity (after an initial learning bump) and in most cases speed improvements.
# experiments with list comprehension # tested with Python24 vegaseat 02feb2006 import random # random.sample(), random.shuffle() import textwrap # textwrap.fill() import string # string.punctuation # create a list of integer numbers numList = range(24) print "List of numbers 0 to 23:" print numList # this shows you the development of list comprehension # creating a list of odd numbers from the above list # the traditional way, no list comprehension ... oddList1 =  for x in numList: if x % 2 != 0: oddList1.append(x) # interim version of list comprehension ... # (uses all the above statements) # notice that the total list comprehension is enclosed in [ ] oddList2 =  [oddList2.append(x) for x in numList if x % 2 != 0] # final (simplified) version of list comprehension ... oddList3 = [x for x in numList if x % 2 != 0] # test the results print "\nList of odd numbers from 1 to 23:" print "oddList1 =", oddList1 print "oddList2 =", oddList2 print "oddList3 =", oddList3 print # get the maximum integer less or equal to a given integer def max_le(seq, val): '''return max element of sequence less than or equal to val''' return max([v for v in seq if v <= val]) # create a list of 10 random integers in the range 0 to 99 and test max_le() randomList = random.sample(xrange(100), 10) print randomList try: num = 7 result = max_le(randomList, num) print "Maximum integer less or equal to %d in above list: %d" % (num, result) except: print "All numbers in the above list exceed %d" % num print # create a deck of cards: cards = [suit + rank for suit in "CDHS" for rank in "A23456789TJQK"] print "Show the first 13 cards (suit + rank eg. CA = ace of club, CT = ten of club):" print cards[:13] # ['CA', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', 'CT', 'CJ', 'CQ', 'CK'] # shuffle the cards: random.shuffle(cards) print "Show a hand of 5 shuffled cards:" hand = cards[:5] print hand print "Hand sorted by suit:" print sorted(hand) # to sort by rank you can change to rank + suit (eg. C7 becomes 7C) then sort # again, list comprehension is used hand1 = sorted([card[1:2] + card[0:1] for card in hand]) #print hand1 # test # change back to suit + rank (7C changes back to C7) hand2 = [card[1:2] + card[0:1] for card in hand1] print "Hand sorted by rank:" print hand2 print # list pi values progressively rounded off print "List of pi values progressively rounded off:" piList = [str(round(355/113.0, k)) for k in range(1,6)] print piList print # use list comprehension to remove duplicate elements gwb = "We got into deficit because the economy went into the recession that is how we got into deficit" rawList = gwb.split() print "The raw list containing duplicates:" print rawList # create an empty list uniqueList =  [uniqueList.append(str1) for str1 in rawList if not uniqueList.count(str1)] print "\nThe unique list (no duplicates):" print uniqueList print # remove leading and trailing spaces from strings fruitList = [' banana', ' loganberry ', 'passion fruit '] print "Original list = ", fruitList stripList = [fruit.strip() for fruit in fruitList] print "Stripped leading/trailing spaces = ", stripList print print "Remove punctuation marks from a string:" str1 = "47 years ago '_jitter' was almost '_chatter', how about that?" str2 = "".join([c for c in str1 if c not in string.punctuation]) print str1 print str2 print # use list comprehension to compare two lists list1 = [1, 2, 5, 7, 12, 25, 32, 47, 65, 99] list2 = [1, 2, 5, 7, 12, 15, 32, 48, 65, 99] print "list1 =", list1 print "list2 =", list2 print "These are the items different in the two lists:" print [(x, y) for (x, y) in zip(list1, list2) if x != y] print # creating a 10x10 matrix (list of lists) # first create a list of ten elements myList = range(10) # now create a 10x10 matrix of zeros using a nested list comprehension myMatrix = [[0 for k in myList] for k in myList] print "A 10x10 matrix (list of lists) of zeros:" print myMatrix print "Improved display:" for k in myMatrix: print k # insert 1 as a "ulc to lrc diagonal" for k in range(10): myMatrix[k][k] = 1 # display the result print "Added a diagonal of ones:" for k in myMatrix: print k print # convert this string into a list of words str1 = \ """The dynamic declination flag was accidentally switched to EIEIO. Check your atomic memory pool for floaters because they're probably causing the kernel to pop. But be careful because the memory manager is volatile and could cause the entire pipeline to dump core unexpectedly. """ wordList = str1.split(None) # cut the list of words into a list of lists of 5 words or less each cutWordList2 = [wordList[k:k+5] for k in range(0, len(wordList), 5)] # display the result as text (max 5 words per line) print "Text shown with max 5 words per line:" for subList in cutWordList2: line = " ".join(subList) print line print # a word/text wrap that preserves existing line breaks and spaces # uses the module textwrap and list comprehension print "Wrap the text into 35 column space:" sep = "\n\n" print "-"*35 print sep.join([textwrap.fill(line, 35) for line in str1.split(sep)]) print "-"*35
About the Author