views:

129

answers:

5

A simplified version of my problem:

I have a list comprehension that i use to set bitflags on a two dimensional list so:

s = FLAG1 | FLAG2 | FLAG3
[[c.set_state(s) for c in row] for row in self.__map]

All set_state does is:

self.state |= f

This works fine but I have to have this function "set_state" in every cell in __map. Every cell in __map has a .state so what I'm trying to do is something like:

[[c.state |= s for c in row] for row in self.map]

or

map(lambda c: c.state |= s, [c for c in row for row in self.__map])

Except that neither works (Syntax error). Perhaps I'm barking up the wrong tree with map/lamda but I would like to get rid on set_state. And perhaps know why assignment does not work in the list-comprehension

+2  A: 

Yes, you're using the wrong tool. A list comprehension returns a completely new value, so you might be able to do this:

self.__map = [[c.state | s for c in row] for row in self.__map]

But my instinct is that you should just be using two for loops:

for row in self.__map:
    for c in row:
        c.state |= s

In a list comprehension, the result has to be an expression. That's because your double comprehension is just sugar for this:

list1 = []
for row in self.__map:
    list2 = []
    for c in row:
        list2.append(c.state | s)
    list1.append(list2)
self.__map = list1

It makes no sense to say

        list2.append(c.state |= s)

Because the innermost expression has to return something to be appended to list2.

Basically, the list comprehensions make a complete new copy of self.__map each time you update the flags. If that's what you want, then go with it. But I suspect you just want to change the existing map. In that case, use the double for loops.

Nathan Sanders
+4  A: 

List comprehensions are for creating lists. You don't seem to care about the actual lists you are making, so you should just use a for statement, like so:

for row in self.__map:
    for c in row:
        c.state |= s
Thomas Wouters
A: 

Use the setattr function:

setattr(c, "state", s)

And then read up on Statementless Python.

jleedev
A: 

You don't want a list comprehension, since you're modifying your data in-place, not creating a new list.

Do a loop.

fortran
A: 

In python assignments are statements, not expressions which are only allowed in lambdas and list comprehension.

Łukasz