1) If you write (...) after a function name, it executes the function(except when defining a function). And when you write (...) after a function name it's known as a "function call":
def calc(): return 3.5 result = calc() + 2 2) Function calls are replaced in the code by the function's return value: result = calc() + 2 becomes: result = 3.5 + 2 3) map() and zip() perform two different tasks. zip() takes two(or more) sequences, and it returns a list of tuples, where each tuple consists of one element from each of the sequences: s1 = [1, 2, 3] s2 = [10, 20, 30, 40] print zip(s1, s2) --->[(1, 10), (2, 20), (3, 30)] If one sequence is shorter than the other, zip() stops when it reaches the end of the shorter sequence. On the other hand, map() applies a given function to each member of a sequence and returns a list that contains the return values of the function: s1 = [1, 2, 3] def f(x): return x*2 result = map(f, s1) print result ---->[2, 4, 6] If you call map() with a function and two sequences, e.g.: map(f, s1, s2) then the specified function will be called with two arguments--using one element from each sequence for the arguments: s1 = [1, 2, 3] s2 = [10, 20, 30] def f(x,y): return x + y result = map(f, s1, s2) print result ----->[11, 22, 33] If one sequence is shorter than the other, then unlike zip() which stops at the end of the shorter sequence, map() continues on until it reaches the end of the longer sequence. In that case, since the shorter sequence won't have any more values to provide, map() uses None. In other words, map() calls the specified function with one argument from the longer sequence and the other argument being None: s1 = [1, 2, 3] s2 = [10, 20, 30, 40, 50] def f(x,y): return x + y result = map(f, s1, s2) print result Traceback (most recent call last): File "2pythontest.py", line 7, in ? result = map(f, s1, s2) File "2pythontest.py", line 5, in f return x + y TypeError: unsupported operand type(s) for +: 'NoneType' and 'int' The error results from the attempt inside the function f to add the value 40 from the second sequence to None(which is used in lieu of a value from the first sequence). So if you want to use map() with sequences of different lengths, before you perform any calculations in the specified function, you have to first check to see if one of the values is None. If one of the values is None, then you have to take some special action: s1 = [1, 2, 3] s2 = [10, 20, 30, 40, 50] def f(x,y): if x==None or y==None: return "N/A" return x + y result = map(f, s1, s2) print result ---->[11, 22, 33, 'N/A', 'N/A'] > for x,y in map(None, lista, listb): # Also fine - extends as > expected > print "MAP:", x, "<<x y>>", y That is not expected at all--at least not by me. You have to decipher the fine print of the map() description to expect that result. My expectation is the code will fail since None is not a function, and the first argument to map() is supposed to be a function. In any case, that should be considered aberrant behavior--not the normal way map() works. > for x,y in map("N/A", lista, listb): ########## Fails - Can not call a > 'str' > print "MAP:", x, "<<x y>>", y That is as expected since "N/A" is not a function. After all, how can you call a string? s = "hello world" print s(10) Obviously, that's nonsensical. > def fillwith(fillchars): > return fillchars > > for x,y in map(fillwith("N/A"), lista, listb): ########## Fails also - > Can not call a 'str' In the last line of code, the function call is replaced in the code by the function's return value(see point 2 above--at the very top of the post). Since the return value of the function call fillwith("N/A") is "N/A", the last line of your code becomes: for x,y in map("N/A", lista, listb) and once again map() is unable to call a string: s = "N/A" print s(lista[0], listb[0]) In conclusion, zip() returns a list of tuples (where each tuple contains one element from each sequence). map() returns a list (where each element of the list is the return value of a function). -- http://mail.python.org/mailman/listinfo/python-list