[Tutor] "if clause" in list comprehensions.

vince spicer vinces1979 at gmail.com
Mon Oct 19 22:14:55 CEST 2009


On Mon, Oct 19, 2009 at 1:58 PM, Emile van Sebille <emile at fenx.com> wrote:

> On 10/19/2009 12:20 PM Alan Gauld said...
>
>
>> "Sander Sweers" <sander.sweers at gmail.com> wrote
>>
>>  mylist = ['John', 'Canada', 25, 32, 'right']
>>>> a = [item.upper() for item in mylist if type(item) == type('good')]
>>>>
>>>
>>> Usually it is recommended to use hasattr() instead of type()
>>>   hasattr(s, 'upper')
>>>
>>
>> Nope, they do  completely different things
>> I think you might be thinking of isinstance() which can be used instead of
>> type(). I see you use hasattr as a means of testing for a method but that is
>> still different from testing type - the method names might be the same but
>> the functions be completely different in effect!
>>
>>  returned this: ['JOHN', 'CANADA', 'RIGHT']
>>>> I was expecting this: ['JOHN', 'CANADA', 25, 32, 'RIGHT']
>>>> So, actually the "if" acted like a filter.
>>>>
>>>
>> It is intended to be used as a filter.
>>
>>  In order to use a list comprehension I created this function instead.
>>>> def upperfy(item)
>>>>   try:
>>>>       item = item.upper()
>>>>   except AttributeError:
>>>>       pass
>>>>   return item
>>>>
>>>
>>  I would move return item under the except and remove the pass, other
>>> might disagree on this.
>>>
>>
>> I would :-)
>> Doing that would result in None being returned for each successful
>> conversion. The OPs code is correct (even if unnecessary)
>>
>>  a = [upperfy(item) for item in mylist]
>>>>
>>>
>> a = [item.upper() if type(item) == str else item for item in mylist]
>>
>> should do it I think.
>>
>
> or even
>
>  a = [ str(item).upper() for item in mylist ]
>
> Emile
>
>
>
>> HTH,
>>
>>
>>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>


Lambda can save the day to keep everything on one line, and leave variable
type the same:

mylist = ['John', 'Canada', 25, 32, 'right']
new_list = [(lambda y: y.upper() if hasattr(y, 'upper') else y)(a) for a in
x]

>>  ['JACK', 'CANADA', 25, 32, 'RIGHT']

Vince
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20091019/33059556/attachment-0001.htm>


More information about the Tutor mailing list