0

I have found this and this, but as far as I can understand, I believe that I am not duplicating those questions.

While tinkering around to write the shortest code I can write to find the powerset of a set, I came across this behavior:

lst = [1,2,3]
powerset = set([()])

[powerset.update([subset + tuple([x]) for subset in powerset]) for x in lst]

print 'powerset:', sorted(powerset, key = lambda x: len(x))

> powerset: [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]

What puzzles me further is that powerset is updated even when the list that results from the list comprehension is something quite different.

lst = [1,2,3]
powerset = set([()])
holy_ghost = [powerset.update([subset + tuple([x]) for subset in powerset]) for x in lst]

print 'holy_ghost:', holy_ghost
print 'powerset:',sorted(powerset, key = lambda x: len(x))
print type(powerset),', len:', len(powerset)

> holy_ghost: [None, None, None]
> powerset: [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
> <type 'set'> , len: 8

Here is the nested-loop version of the list comprehension, which needs a "dummy" variable to avoid a "Set changed size during iteration" runtime error.

lst2 = [1,2,3]
powerset2 = set([()])
for x in lst2:
    dummy = set(powerset2)
    for subset in powerset2:
        dummy.update([subset + tuple([x])])
    powerset2 = dummy
print sorted(powerset2, key = lambda x: len(x)) 

[(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]

Question: In python 2.7, is this an intended and acceptable use for list comprehension style code that is safe to use?

I am not a programmer so I will be grateful if you pitch it at my level (beginner + / intermediate –) :)

Thanks.

Community
  • 1
  • 1
user2738815
  • 1,196
  • 3
  • 12
  • 19
  • You are using the list comp only for the side effects. Don't do that. The equivalent without is `for x in lst: powerset.update([subset + tuple([x]) for subset in powerset])` (no temp vars needed). The `powerset.update()` call returns `None` which is why you see your `[None, None, None]` result. – Martijn Pieters Mar 10 '17 at 23:28
  • `somevar.update` (works for sets and dicts) works *in-place*: it updates `somevar`, but it does not return any value; which in Python means, it returns `None`. Thus, you're updating `powerset` inside a list comprehension, but as it returns `None` for each update, your final list comprehension contains just `None`s. Depending on what final result you want, you can use this behaviour, or rewrite your list comprehension to contain whatever you want. –  Mar 10 '17 at 23:31

0 Answers0