[BangPypers] if not with comparision statement in python

Dhananjay Nene dhananjay.nene at gmail.com
Mon Aug 1 15:57:37 CEST 2011


On Mon, Aug 1, 2011 at 5:44 PM, Dhananjay Nene <dhananjay.nene at gmail.com> wrote:
> On Mon, Aug 1, 2011 at 5:07 PM, Anand Chitipothu <anandology at gmail.com> wrote:
>> 2011/8/1 Dhananjay Nene <dhananjay.nene at gmail.com>:
>>> On Mon, Aug 1, 2011 at 4:17 PM, Anand Chitipothu <anandology at gmail.com> wrote:
>>>> 2011/8/1 Dhananjay Nene <dhananjay.nene at gmail.com>:
>>>>> On Sat, Jul 30, 2011 at 2:15 PM, Asif Jamadar <asif.jamadar at rezayat.net> wrote:
>>>>>> What if I have two lists for both minimum and maximum values
>>>>>>
>>>>>> Minimum  Maximum
>>>>>> 0               10
>>>>>> 11              20
>>>>>> 21              30
>>>>>> 31              40
>>>>>>
>>>>>>
>>>>>> Now how should I check if actual result is not laying between above ranges
>>>>>>
>>>>>> if not minimum<=actual_result and  not maximum>=actual_result:
>>>>>>
>>>>>> Any suggestions?
>>>>>
>>>>> def in_range(number) :
>>>>>    return any(map(lambda (x,y) : x <= number <= y,
>>>>>                  ((0,10),(11,20), (21,30), (31,40))))
>>>>
>>>> How about this?
>>>>
>>>> def in_range(number, min_max_pairs):
>>>>    return any(x <= number <=y for x, y in min_max_pairs)
>>>
>>> Definitely better
>>>>
>>>> List comprehensions and generation expressions are usually more
>>>> readable and expressive than using map.
>>>
>>> Thats probably truer for the python and python trained eyes than any
>>> other (in other words its both subjective and contextual and a bit to
>>> do with syntax). Allow me to illustrate :
>>>
>>> If I want to double all elements in a list and then increment them by
>>> one, here's how I would use a map in python
>>>
>>> def double(x) : return x * 2
>>> def increment(x) : return x + 1
>>> print map(increment,map(double,range(5)))
>>>
>>> and here's how I would do it in scala - notice the last (third) line
>>> and consider its readability (I'm sure a scala non-novice will offer
>>> something even superior)
>>>
>>> def double(n: Int) = n * 2
>>> def increment(n: Int) = n + 1
>>> println(0 to 4 map double map increment)
>>>
>>> so readability is often a function of what one's eyes are trained ot
>>> read and also the syntactic capabilities in the language
>>
>> This is just the prefix/postfix thing.
>>
>> Yes, prefix style is difficult to read if there are too many nested
>> levels. Look at lisp code for example. Yes, it feel it awkward when I
>> have to do range(len(x)). Unix pipes and chaining methods are postfix.
>> What you are doing in scala is just that.
>>
>> If map was a list method, I could do this:
>>
>> range(0, 4).map(douple).map(increment)
>>
>> And as unix pipe:
>>
>> seq 0 4 | double | increment
>>
>>> I also find map much more atomic and portable construct to think in -
>>> after all every list comprehension is syntactic sugar around map +
>>> filter, and map/reduce/filter are far more omnipresent than list
>>> comprehensions.
>>
>> Recently, I was thinking about converting a list comprehension to
>> map/filter calls and It turned out that list comprehensions are more
>> than map+filter.
>>
>> [i * i for i in range(10)]  ~ map(lambda i*i, range(10))
>>
>> [i * i for i in range(10) if i % 2 == 0] ~  map(lambda i*i,
>> filter(lambda i%2 == 0, range(10)))
>>
>> But the situation gets tricky when there are multiple loop items in
>> the list comprehension.
>>
>> Here is a list comprehension to find all Pythagorean triplets below 100.
>>
>> [(x, y, z) for x in range(1, 50) for y in range(x, 100) for z in
>> range(y, 100) if x*x + y*y == z*z]
>>
>> Try converting this into map/filter and you'll understand the difference.
>>
>
> Well, I cheated - there's one more important function (which at least
> I haven't seen in the python library - flatmap)
>
> I constructed my own version
>
> I also constructed my own append_to_list since I didn't know how to
> implement it as a lambda
>
> Here's the code
>
I knew there was a way to better implement flatmap - its a combination
of itertools.chain.from_iterable and map. Here's a much cleaner code

from itertools import chain

print filter(lambda (x,y,z) : x*x + y*y == z*z,
    chain.from_iterable(map(
        lambda x: chain.from_iterable(map(
            lambda y: chain.from_iterable(map(
                lambda z: [[x,y,z]],
                range(y,100))),
            range(x,100))),
        range(1,50))))

PS: There are no more functions required (that I cheated about :))
map, reduce, filter, flatmap equivalent should do it.


More information about the BangPypers mailing list