Ask Your Question
0

Testing for list membership

asked 10 years ago

schmu gravatar image

I'd like to adopt Sage in my teaching this fall, so I've started to play around with some basic manipulations that I would expect my students to be able to do. I am an absolute beginner in Sage and Python.

Suppose that I want all the partitions of 6 that contain the number "2". My first attempt failed:

L=Partitions(6).list(); L

[[6], [5, 1], [4, 2], [4, 1, 1], [3, 3], [3, 2, 1], [3, 1, 1, 1], [2, 2, 2], [2, 2, 1, 1], [2, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1]]

[j for j in L if j.count(2)>0]

"Error in lines 1-1\nTraceback (most recent call last):\n
File \"/projects/6313dd6a-b1df-46ed-885a-a1bdf71f3fc3/.sagemathcloud/sage_server.py\", line 879, in execute\n exec compile(block+'\n', '', 'single') in namespace, locals\n File \"\", line 1, in <module>\n File \"sage/structure/element.pyx\", line 431, in sage.structure.element.Element.__getattr__ (build/cythonized/sage/structure/element.c:4644)\n
return getattr_from_other_class(self, P._abstract_element_class, name)\n File \"sage/structure/misc.pyx\", line 253, in sage.structure.misc.getattr_from_other_class (build/cythonized/sage/structure/misc.c:1582)\n
raise dummy_attribute_error\nAttributeError: 'Partitions_n_with_category.element_class' object has no attribute 'count'\n"

However, if I create a new list E by copying and pasting the above, it works fine.

E=[[6], [5, 1], [4, 2], [4, 1, 1], [3, 3], [3, 2, 1], [3, 1, 1, 1], [2, 2, 2], [2, 2, 1, 1], [2, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1]]

[j for j in E if j.count(2)>0]

[[4, 2], [3, 2, 1], [2, 2, 2], [2, 2, 1, 1], [2, 1, 1, 1, 1]]

Is there a better way to do this, without copying and pasting??

Preview: (hide)

1 Answer

Sort by » oldest newest most voted
1

answered 10 years ago

tmonteil gravatar image

updated 10 years ago

You should notice that the elements of L are not lists, but partitions (that do not provide a count() method as you saw with the AttributeError):

sage: L[0]
[6]
sage: L[0].parent()
Partitions of the integer 6
sage: type(L[0])
<class 'sage.combinat.partition.Partitions_n_with_category.element_class'>

Of course, you can transform them as lists with the list function:

sage: list(L[0])
[6]
sage: type(list(L[0]))
<type 'list'>

Hence, you can do;

sage: [j for j in L if list(j).count(2)>0]
[[4, 2], [3, 2, 1], [2, 2, 2], [2, 2, 1, 1], [2, 1, 1, 1, 1]]

But more elegantly, instead of counting, you can check that 2 belongs to the partition with the in operator:

sage: [j for j in L if 2 in j]
[[4, 2], [3, 2, 1], [2, 2, 2], [2, 2, 1, 1], [2, 1, 1, 1, 1]]
Preview: (hide)
link

Comments

Thanks very much, this is exactly what I needed!

schmu gravatar imageschmu ( 10 years ago )

Thierry, isn't there also an option somewhere in http://doc.sagemath.org/html/en/refer... to get this directly?

kcrisman gravatar imagekcrisman ( 10 years ago )

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 10 years ago

Seen: 1,930 times

Last updated: Jun 04 '15