[Tutor] list comprehensions

Gregor Lingl glingl@aon.at
Wed, 21 Aug 2002 11:05:39 +0200


Sean 'Shaleh' Perry schrieb:

>On Tuesday 20 August 2002 08:29 pm, Tim Wilson wrote:
>  
>
>>Hi everyone,
>>
>>I'm wondering if it's possible to implement the following function using
>>list comprehensions. It's not really a speed issue because it runs in a
>>split second using the built-in dictionary on my Linux box.
>>
>>-Tim
>>
>>def filterLongest(words):
>>    """
>>    Filter a list of words for all words that have a length equal to the
>>    longest word in the list.
>>
>>    Argument:
>>    words -- List of words to filter
>>
>>    """
>>    l = []
>>    maxLength = 0
>>    for word in words:
>>        wordLength = len(word)
>>        if wordLength == maxLength:
>>            l.append(word)
>>        elif wordLength > maxLength:
>>            l = [word]
>>            maxLength = wordLength
>>    return l
>>    
>>
>
>this code actual has a fairly big bug.
>
>['a', 'bb', 'ccc', 'dddd', 'eeeee', ...]
>
>given that list each item will end up in the return.  You really need to loop 
>twice.  Once to find the longest word then again to find those that are at 
>least as big.  Or did I misunderstand your comment?  For instance given my 
>example list above the return list would simply be:
>
>['z' * 26]
>  
>

I disagree:

 >>> tl
['a', 'bb', 'ccc', 'dddd', 'eeeee']
 >>> filterLongest(tl)
['eeeee']
 >>> filterLongest(tl*4)
['eeeee', 'eeeee', 'eeeee', 'eeeee']
 >>>

imho this is what is intended. In the above code l collects all the 
words having
 length of the longest word encountered so far. If a longer word occurs
l is replaced by a new list containing only this one which then may be
appended to.

And concerning list-comprehension:
I only see the possibility to use it, if  maxLenght is known. This may 
for instance determined like this.

 >>> map(len,tl)
[1, 2, 3, 4, 5]
 >>> max(map(len,tl))
5

So we get the desired result with

 >>> [word for word in tl if len(word) == max(map(len,tl))]
['eeeee']
 >>> [word for word in tl*4 if len(word) == max(map(len,tl))]
['eeeee', 'eeeee', 'eeeee', 'eeeee']
 >>> tl.append("hehee")
 >>> [word for word in tl if len(word) == max(map(len,tl))]
['eeeee', 'hehee']
 >>>

Gregor