Victor via Python-list wrote: > On Saturday, September 22, 2018 at 6:22:32 AM UTC-7, Peter Otten wrote: >> Victor via Python-list wrote: >> >> > Let me use a different input args and display them below. Basically, I >> > am >> > hoping to add up all elements of each nested list. So at first it >> > should >> > start with [1,11,111] ==> 1+11+111 = 123. But instead, it appears to >> > take >> > the 1st element from each nested list to add up [1,2,3] = 6. How >> > should >> > it be corrected? Thx. >> >> I see three options. You can >> >> (1) use a list comprehension >> >> [add_all_elements(*sub) for sub in alist] >> >> (2) replace map() with itertools.starmap() >> >> list(itertools.starmap(add_all_elements, alist)) >> >> (3) change your function's signature from add_all_elements(*args) to >> add_all_elements(args), either by modifying it directly or by wrapping it >> into another function >> >> list(map(lambda args: add_all_elements(*args), alist)) >> >> (3a) My personal preference would be to change the signature and then use >> the list comprehension >> >> def add_all_elements(args): ... >> [add_all_elements(sub) for sub in alist] > > Hi Peter, > Thank you for your suggested solutions. They all work. But I just want > to know what is wrong with my doing: > > list(map(add_all_elements,*alist)) > > Theoretically, each list element is passed to add_all_elements. And if my > alist is [[1, 11, 111], [2, 22, 222], [3, 33, 333]], then the 1st list > element must be this [1,11,111] passed as args into add_all_elements. > > In other words, the following should have happened: > >>>> add_all_elements (*[1,11,111])
That's not what happens. Try it with a function that passes through its arguments unchanged: >>> items = [[1, 11, 111], [2, 22, 222], [3, 33, 333]] >>> list(map(lambda *args: args, *items)) [(1, 2, 3), (11, 22, 33), (111, 222, 333)] The star before items is evaluated directly rather than magically passed on to the call of add_all_elements. map(f, *items) is equivalent to map(f, items[0], items[1], items[2]) which calls f with f(items[0][0], items[1][0], items[2][0]) f(items[0][1], items[1][1], items[2][1]) f(items[0][2], items[1][2], items[2][2]) If you think of your list of lists as a matrix that matrix is effectively transposed (x and y axis are swapped). >>> list(map(lambda *args: sum(args), *items)) [6, 66, 666] In principle you could transpose the matrix twice >>> list(map(lambda *args: sum(args), *zip(*items))) [123, 246, 369] but that's not a very efficient approach. Another gotcha to be aware of is that map() (and zip()) stop when the shortest argument ends: >>> list(map(lambda *args: sum(args), [], *items)) [] >>> list(map(lambda *args: sum(args), [42], *items)) [48] >>> list(map(lambda *args: sum(args), [42, 42], *items)) [48, 108] >>> list(map(lambda *args: sum(args), [42, 42, 42, 42, 42], *items)) [48, 108, 708] -- https://mail.python.org/mailman/listinfo/python-list