Strange generator problem

J

Joost Cassee

Hello all,


I bumped into an unexpected problem using generators. Consider this code:

def test(s):
return _test([], [], s)
def _test(s1, s2, s):
if s:
s1.append(s.pop())
for x in _test(s1, s2, s):
yield x
s2.append(s1.pop())
for x in _test(s1, s2, s):
yield x
s.append(s2.pop())
else:
yield s1, s2

The test function is supposed be a generator returning all combinations
of dividing the elements of the input list into two distinct lists
(order of elements unimportant). (This post is not about the quality of
the solution. :) )

Consider now the result of using the generator in a for-loop and in the
list function (same result for list comprehension):
.... print x
....
([2, 1, 0], [])
([2, 1], [0])
([2, 0], [1])
([2], [1, 0])
([1, 0], [2])
([1], [2, 0])
([0], [2, 1])
([], [2, 1, 0])[([], []), ([], []), ([], []), ([], []), ([], []), ([], []), ([], []),
([], [])]

The following (simpler) generator works as expected:
.... for x in s:
.... yield x
....[0, 1, 2]

Can anyone explain the difference? The python version is 2.5.1.


Regards,

Joost
 
P

Paul Hankin

Hello all,

I bumped into an unexpected problem using generators. Consider this code:

def test(s):
return _test([], [], s)
def _test(s1, s2, s):
if s:
s1.append(s.pop())
for x in _test(s1, s2, s):
yield x
s2.append(s1.pop())
for x in _test(s1, s2, s):
yield x
s.append(s2.pop())
else:
yield s1, s2

Lists aren't copied when they're yielded, so you're returning the same
lists (with different elements) each time. Your final list looks like
[(s1, s2), (s1, s2), ...] and as it happens, s1 and s2 are both [] by
the end.

You can fix it by copying the lists manually before yielding them, or
using a better sub-list algorithm :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,602
Members
45,185
Latest member
GluceaReviews

Latest Threads

Top