简体   繁体   中英

Python List Comprehension with Sum

I have some python code that looks like this:

mat = [[3], [4], [4], [0], [1, 2]]
nwalls = 5*[1]
for i in range(1,3):
    nwalls = [sum(nwalls[k] for k in mat[j]) for j in range(5)]
# nwalls = [1, 2, 2, 1, 2]

I can't for the life of me unroll this into syntax without using list comprehension for me to understand. Please assist.

The direct translation would be

mat = [[3], [4], [4], [0], [1, 2]]
nwalls = 5*[1]
for i in range(1, 3):
    _nwalls = []
    for j in range(5):
        tot = 0                # - sum
        for k in mat[j]:       #  /
            tot += nwalls[k]   # /
        _nwalls.append(tot)
    nwalls = _nwalls

(nwalls[k] for k in mat[j]) it self is a generator, in python repl, you can check it as:

>>> y = (x for x in range(10))
>>> type(y)
<class 'generator'>

and sum can take a generator, as sum( (x for x in range(10)) ) , and as PEP289 said

if a function call has a single positional argument, it can be a generator expression without extra parentheses, but in all other cases you have to parenthesize it.

so it looks like sum(x for x in range(10))

instead of recreating the nwalls list every time just assign a new value to the specific slot in the list, just keep a record of the previous values in the list so that you do not end up using the value generated earlier in the loop:

mat = [[3], [4], [4], [0], [1, 2]]
nwalls = 5*[1]
prev_nwalls = 5*[1]
for _ in range(1,3):
    for j in range(5):
        nwalls[j] = sum(prev_nwalls[k] for k in mat[j])
    prev_nwalls[:] = nwalls

assert nwalls == [1, 2, 2, 1, 2]

If you want to avoid comprehension completely first know that the python equivelent to the sum builtin looks something like this:

def sum(iterable):
    s = 0
    for n in iterable:
        s+=n
    return s

So the line nwalls[j] = sum(prev_nwalls[k] for k in mat[j]) would be replaced with something like:

s = 0
for k in mat[j]:
    s+=nwalls[k]
nwalls[j] = s

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM