Ask Your Question
0

Testing for list membership

asked 2015-06-04 00:49:37 +0100

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??

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2015-06-04 01:20:18 +0100

tmonteil gravatar image

updated 2015-06-04 01:22:07 +0100

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]]
edit flag offensive delete link more

Comments

Thanks very much, this is exactly what I needed!

schmu gravatar imageschmu ( 2015-06-04 01:30:23 +0100 )edit

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

kcrisman gravatar imagekcrisman ( 2015-06-04 04:06:39 +0100 )edit

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: 2015-06-04 00:49:37 +0100

Seen: 1,845 times

Last updated: Jun 04 '15