0
import itertools

def powerSet(items):
    '''
    items : a list
    returns all possible combinations of the items
    '''
    return itertools.chain.from_iterable(itertools.combinations(items,r) 
                                           for r in range(len(items)+1))

items = [1,2,3]

If I try

print(powerSet(items))

it returns

<itertools.chain object at 0x113e43588>

but if I try

print(list(powerSet(items))) 

it gives me the list of all subsets.

Why is that?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Dayson D
  • 321
  • 2
  • 7
  • 2
    It returns an iterable, which you are seeing. When you call `list` on the iterable, it makes a list out of the iterable. – juanpa.arrivillaga Mar 07 '18 at 20:15
  • More specifically, it returns an *iterator*. Almost all the functions in `itertools` return iterators, since that's the module's purpose. – Blckknght Mar 07 '18 at 20:17

1 Answers1

1

Because itertools.chain.from_iterable returns an object which you have to iterate, in order to consume elements. Passing the iterable to list is one such way to consume the entire iterable. Chain should not and will not iterate the input automatically.

This is the "lazy" design philosophy behind most of the itertools module, and allows you to process data pipelines element-by-element. For example, if you were iterating data coming in from a socket, you do not want to consume the iterable all at once because it can block, or it might be never-ending.

wim
  • 338,267
  • 99
  • 616
  • 750