Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

set.union() complains that it has no argument when passing in a generator

This is from page 204 of Python for Data Analysis by Wes Mckinney

genre_iter = (set(x.split('|')) for x in movies.genres)
genres = sorted(set.union(*genre_iter))

This code works perfectly when using the %paste method in IPython. The code also works perfectly when run in Python shell. However, when I type the second line into IPython directly, without the %paste method

genres = sorted(set.union(*genre_iter))

I get the following error

TypeError: descriptor 'union' of 'set' object needs an argument

this appears to be a bug, unless there is a feature of IPython that I am still unaware of.

like image 825
michael_j_ward Avatar asked Feb 06 '13 02:02

michael_j_ward


1 Answers

You have exhausted the generator. Re-define it before using it again:

genre_iter = (set(x.split('|')) for x in movies.genres)
genres = sorted(set.union(*genre_iter))

In python, once you have looped over all the elements of an iterator, you cannot loop over the iterator again (it is now empty).

Because the genre_iter iterator is empty, you are not passing any arguments to set.union() and it thus complains:

>>> set.union()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: descriptor 'union' of 'set' object needs an argument

Just to be explicit: you did not find a bug in ipython. You can reproduce the same issue in a regular python prompt.

like image 138
Martijn Pieters Avatar answered Oct 11 '22 15:10

Martijn Pieters