ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Fri, 17 Sep 2010 02:01:26 +0200Comparing listshttps://ask.sagemath.org/question/7689/comparing-lists/This is probably too basic. If so, I apologize (where should I look for questions like this, if that is the case?). (And I'm not sure I chose the right tag either...)
How do I check all the members of a list are contained in another list? Specifically, I'm interested in lists that consist of (prime) numbers. Perhaps there is a more efficient method in this case?Wed, 15 Sep 2010 03:27:20 +0200https://ask.sagemath.org/question/7689/comparing-lists/Answer by mvngu for <p>This is probably too basic. If so, I apologize (where should I look for questions like this, if that is the case?). (And I'm not sure I chose the right tag either...)</p>
<p>How do I check all the members of a list are contained in another list? Specifically, I'm interested in lists that consist of (prime) numbers. Perhaps there is a more efficient method in this case?</p>
https://ask.sagemath.org/question/7689/comparing-lists/?answer=11653#post-id-11653You can use a brute-force search by defining your own custom function. This option doesn't assume that elements in your list are unique. Your lists can contain duplicate elements if you want.
sage: def is_sublist(shortlist, longlist):
....: for e in shortlist:
....: if not (e in longlist):
....: return False
....: return True
....:
sage: L = [2, 5, 23]
sage: P = primes_first_n(20); P
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
sage: is_sublist(L, P)
True
sage: L + [23]
[2, 5, 23, 23]
sage: is_sublist(L + [23], P)
True
sage: L.append(next_prime(P[-1])); L
[2, 5, 23, 73]
sage: is_sublist(L, P)
False
sage: is_sublist(L + [23], P)
False
Alternatively, you can use the built-in functions [itertools.imap][1] and [all][2]. The function `itertools.imap` is efficient when your lists are large, e.g. having hundreds or even hundreds of thousands of elements. This second option doesn't care if your lists have duplicate elements.
sage: import itertools
sage: L = [2, 5, 23]
sage: P = primes_first_n(20); P
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
sage: L + [23]
[2, 5, 23, 23]
sage: all(itertools.imap(lambda x: x in P, L))
True
sage: all(itertools.imap(lambda x: x in P, L + [23]))
True
sage: L.append(next_prime(P[-1])); L
[2, 5, 23, 73]
sage: all(itertools.imap(lambda x: x in P, L))
False
sage: all(itertools.imap(lambda x: x in P, L + [23]))
False
Or, as [Mitesh Patel][3] said, you could use [set][4]. This third approach assumes that the elements in each list are unique, i.e. each list doesn't contain duplicate elements.
sage: L = [2, 5, 23]
sage: P = set(primes_first_n(20))
sage: set(L)
set([2, 5, 23])
sage: set(L).issubset(P)
True
sage: set(L + [23])
set([2, 5, 23])
sage: set(L + [23]).issubset(P)
True
sage: L.append(111); L
[2, 5, 23, 111]
sage: set(L)
set([2, 111, 5, 23])
sage: set(L + [111])
set([2, 111, 5, 23])
sage: set(L + [111]).issubset(P)
False
sage: set(L).issubset(P)
False
[1]: http://docs.python.org/library/itertools.html#itertools.imap
[2]: http://docs.python.org/library/functions.html#all
[3]: http://ask.sagemath.org/users/19/mitesh-patel/
[4]: http://docs.python.org/library/stdtypes.html#set-types-set-frozensetWed, 15 Sep 2010 05:25:42 +0200https://ask.sagemath.org/question/7689/comparing-lists/?answer=11653#post-id-11653Comment by Andres Caicedo for <p>You can use a brute-force search by defining your own custom function. This option doesn't assume that elements in your list are unique. Your lists can contain duplicate elements if you want.</p>
<pre><code>sage: def is_sublist(shortlist, longlist):
....: for e in shortlist:
....: if not (e in longlist):
....: return False
....: return True
....:
sage: L = [2, 5, 23]
sage: P = primes_first_n(20); P
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
sage: is_sublist(L, P)
True
sage: L + [23]
[2, 5, 23, 23]
sage: is_sublist(L + [23], P)
True
sage: L.append(next_prime(P[-1])); L
[2, 5, 23, 73]
sage: is_sublist(L, P)
False
sage: is_sublist(L + [23], P)
False
</code></pre>
<p>Alternatively, you can use the built-in functions <a href="http://docs.python.org/library/itertools.html#itertools.imap">itertools.imap</a> and <a href="http://docs.python.org/library/functions.html#all">all</a>. The function <code>itertools.imap</code> is efficient when your lists are large, e.g. having hundreds or even hundreds of thousands of elements. This second option doesn't care if your lists have duplicate elements.</p>
<pre><code>sage: import itertools
sage: L = [2, 5, 23]
sage: P = primes_first_n(20); P
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
sage: L + [23]
[2, 5, 23, 23]
sage: all(itertools.imap(lambda x: x in P, L))
True
sage: all(itertools.imap(lambda x: x in P, L + [23]))
True
sage: L.append(next_prime(P[-1])); L
[2, 5, 23, 73]
sage: all(itertools.imap(lambda x: x in P, L))
False
sage: all(itertools.imap(lambda x: x in P, L + [23]))
False
</code></pre>
<p>Or, as <a href="http://ask.sagemath.org/users/19/mitesh-patel/">Mitesh Patel</a> said, you could use <a href="http://docs.python.org/library/stdtypes.html#set-types-set-frozenset">set</a>. This third approach assumes that the elements in each list are unique, i.e. each list doesn't contain duplicate elements.</p>
<pre><code>sage: L = [2, 5, 23]
sage: P = set(primes_first_n(20))
sage: set(L)
set([2, 5, 23])
sage: set(L).issubset(P)
True
sage: set(L + [23])
set([2, 5, 23])
sage: set(L + [23]).issubset(P)
True
sage: L.append(111); L
[2, 5, 23, 111]
sage: set(L)
set([2, 111, 5, 23])
sage: set(L + [111])
set([2, 111, 5, 23])
sage: set(L + [111]).issubset(P)
False
sage: set(L).issubset(P)
False
</code></pre>
https://ask.sagemath.org/question/7689/comparing-lists/?comment=22644#post-id-22644Thank you! I suspected there was something like issubset, but didn't about about itertools.imap or all. Fri, 17 Sep 2010 02:01:26 +0200https://ask.sagemath.org/question/7689/comparing-lists/?comment=22644#post-id-22644Comment by Jason Bandlow for <p>You can use a brute-force search by defining your own custom function. This option doesn't assume that elements in your list are unique. Your lists can contain duplicate elements if you want.</p>
<pre><code>sage: def is_sublist(shortlist, longlist):
....: for e in shortlist:
....: if not (e in longlist):
....: return False
....: return True
....:
sage: L = [2, 5, 23]
sage: P = primes_first_n(20); P
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
sage: is_sublist(L, P)
True
sage: L + [23]
[2, 5, 23, 23]
sage: is_sublist(L + [23], P)
True
sage: L.append(next_prime(P[-1])); L
[2, 5, 23, 73]
sage: is_sublist(L, P)
False
sage: is_sublist(L + [23], P)
False
</code></pre>
<p>Alternatively, you can use the built-in functions <a href="http://docs.python.org/library/itertools.html#itertools.imap">itertools.imap</a> and <a href="http://docs.python.org/library/functions.html#all">all</a>. The function <code>itertools.imap</code> is efficient when your lists are large, e.g. having hundreds or even hundreds of thousands of elements. This second option doesn't care if your lists have duplicate elements.</p>
<pre><code>sage: import itertools
sage: L = [2, 5, 23]
sage: P = primes_first_n(20); P
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
sage: L + [23]
[2, 5, 23, 23]
sage: all(itertools.imap(lambda x: x in P, L))
True
sage: all(itertools.imap(lambda x: x in P, L + [23]))
True
sage: L.append(next_prime(P[-1])); L
[2, 5, 23, 73]
sage: all(itertools.imap(lambda x: x in P, L))
False
sage: all(itertools.imap(lambda x: x in P, L + [23]))
False
</code></pre>
<p>Or, as <a href="http://ask.sagemath.org/users/19/mitesh-patel/">Mitesh Patel</a> said, you could use <a href="http://docs.python.org/library/stdtypes.html#set-types-set-frozenset">set</a>. This third approach assumes that the elements in each list are unique, i.e. each list doesn't contain duplicate elements.</p>
<pre><code>sage: L = [2, 5, 23]
sage: P = set(primes_first_n(20))
sage: set(L)
set([2, 5, 23])
sage: set(L).issubset(P)
True
sage: set(L + [23])
set([2, 5, 23])
sage: set(L + [23]).issubset(P)
True
sage: L.append(111); L
[2, 5, 23, 111]
sage: set(L)
set([2, 111, 5, 23])
sage: set(L + [111])
set([2, 111, 5, 23])
sage: set(L + [111]).issubset(P)
False
sage: set(L).issubset(P)
False
</code></pre>
https://ask.sagemath.org/question/7689/comparing-lists/?comment=22647#post-id-22647FYI, I find
sage: A = range(10^4)
sage: B = range(1,10^4,2)
sage: all(x in A for x in B)
True
to be as fast or faster than any of the option above. Perhaps there is a case that I'm missing where imap is faster, though.Wed, 15 Sep 2010 17:29:30 +0200https://ask.sagemath.org/question/7689/comparing-lists/?comment=22647#post-id-22647