[Python-ideas] Fast sum() for non-numbers

Ron Adam ron3200 at gmail.com
Sun Jul 7 06:01:12 CEST 2013



On 07/06/2013 09:32 PM, Steven D'Aprano wrote:
> On 07/07/13 12:14, Ron Adam wrote:
>
>> Take the following example.
>>
>>         def add_to_values(vs, v):
>>             return [n + v for n in vs]
>
> I don't actually see the point of this example, but I'm willing to bear
> with you.

Yes, It's over simplified to highlight a concept rather than have a 
specific programming problem to solve.


>> Now what do you suppose this should do?
>>
>> Well it it depends on what vs and v are.  It might add a value to each
>> item in a list of values, it might add a value to each byte in a bytes
>> string, it might concatenate a string to each string in a list, or it
>> might join a sequence to each sequence in a list.  Sounds reasonable
>> doesn't it?
>>
>> Now consider that in some companies, programmers are required to take
>> great care to be sure that the routines that they write can't do the
>> wrong thing with lots of testing to back that up.
>>
>> That simple routine "ideally" should be dead simple, but now it requires
>> some added care to be sure it can't do the wrong thing.  Which could also
>> slow it down.  :/
>
> Can you give an actual example of the above add_to_values function doing
> the wrong thing?

It was kept simple to demonstrate a concept.

What I was trying to demonstrate is it has to do with the context it's used 
in, and not something wrong with the example it self.  It will do what it 
it says it will do.

Sometimes we want very general behaviour, and sometime we don't want that. 
  Both are good, but it should be easy to do both in a simple way.  That is 
the point I was trying to make.


>> Generalised routines are very nice and can save a lot of work, but it is
>> easier to add behaviours than it is to limit unwanted behaviours.  The
>> problem here is that the different behaviours use a similar operator at a
>> very low level.
>>
>> But, can we change this?  Probably not any time soon.  It would mean
>> changing __add__, __iadd__, __mul__, __rmul__, __imul__, and possibly a
>> few others for a lot of different objects to get a clean separation of
>> the behaviours.  And we would need new symbols and method names to
>> replace those.
>>
>> So the question becomes how we be more specific in a case like this and
>> avoid the extra conditional expression.  This is one way...
>>
>>>>> def add_value_to_many(value, many):
>> ...         return [int.__add__(x, value) for x in many]
>> ...
>>>>> add_value_to_many(4, [3, 6, 0])
>> [7, 10, 4]
>>>>> add_value_to_many("abc", "efg")
>> Traceback (most recent call last):
>>    File "<stdin>", line 1, in <module>
>>    File "<stdin>", line 2, in add_value_to_many
>>    File "<stdin>", line 2, in <listcomp>
>> TypeError: descriptor '__add__' requires a 'int' object but received a 'str'
>>
>> It rejects the unwanted cases without the test.  But different operators
>> would have been a bit nicer.
>
> This doesn't make sense to me. Above, you just said that "concatenate a
> string to each string in a list" was reasonable, and here you prohibit it.

You missed the question mark right after "reasonable".

Yes, it's an example of how to do that if you need to do it.  Otherwise you 
need to add a isinstance() check or something else to get that.

Cheers,
    Ron









More information about the Python-ideas mailing list