correct style for element-wise operations on lists without numpy (python)
Question: I would like to operate on lists element by element without using numpy, for
example, i want `add([1,2,3], [2,3,4]) = [3,5,7]` and `mult([1,1,1],[9,9,9]) =
[9,9,9]`, but i'm not sure which way of doing is it considered 'correct'
style.

The two solutions i came up with were

    
    
    def add(list1,list2):
        list3 = []
        for x in xrange(0,len(list1)):
            list3.append(list1[x]+list2[x])
        return list3
    
    def mult(list1, list2):
        list3 = []
        for x in xrange(0,len(list1)):
            list3.append(list1[x]*list2[x])
        return list3
    
    def div(list1, list2):
        list3 = []
        for x in xrange(0,len(list1)):
            list3.append(list1[x]/list2[x])
        return list3
    
    def sub(list1, list2):
        list3 = []
        for x in xrange(0,len(list1)):
            list3.append(list1[x]-list2[x])
        return list3
    

where each operator is given a separate function

and

    
    
    def add(a,b)
        return a+b
    def mult(a,b)
        return a*b
    def div(a,b)
        return a/b
    def sub(a,b)
        return a-b
    def elementwiseoperation(list1, list2, function):
        list3 = []
        for x in xrange(0,len(list1)):
            list3.append(function(list1[x],list2[x]))
        return list3
    

where all the basic functions are defined, and I have a separate function to
use them on each element. I skimmed through PEP8, but didn't find anything
directly relevant. Which way is better?


Answer: The normal way to do this would be to use `map` or `itertools.imap`:

    
    
    import operator
    multiadd = lambda a,b: map(operator.add, a,b)
    print multiadd([1,2,3], [2,3,4]) #=> [3, 5, 7]
    

Ideone: <http://ideone.com/yRLHxW>

`map` is a c-implemented version of your `elementwiseoperation`, with the
advantage of having the standard name, working with any iterable type and
being faster.

Alternatively, you could use `partial` and `map` for a pleasingly pointfree
style:

    
    
    import operator
    import functools
    
    multiadd = functools.partial(map, operator.add)
    print multiadd([1,2,3], [2,3,4]) #=> [3, 5, 7]
    

Ideone: <http://ideone.com/BUhRCW>

Anyway, you've taken the first steps in functional programming yourself. I
suggest you read around the topic.

As a general matter of style, iterating by index using `range` is generally
considered the wrong thing, if you want to visit every item. The usual way of
doing this is simply to iterate the structure directly. Use `zip` or
`itertools.izip` to iterate in parallel:

    
    
    for x in l:
        print l
    
    for a,b in zip(l,k):
        print a+b
    

And the usual way to iterate to create a list is not to use `append`, but a
list comprehension:

    
    
    [a+b for a,b in itertools.izip(l,k)]
    

