mirror of https://github.com/python/cpython
Add set.isdisjoint()
This commit is contained in:
parent
004c1c1562
commit
1760c8a017
|
@ -1467,6 +1467,13 @@ operations:
|
|||
|
||||
Test *x* for non-membership in *s*.
|
||||
|
||||
.. method:: set.isdisjoint(other)
|
||||
|
||||
Return True if the set has no elements in common with *other*.
|
||||
Sets are disjoint if and only if their interesection is the empty set.
|
||||
|
||||
.. versionadded:: 2.6
|
||||
|
||||
.. method:: set.issubset(other)
|
||||
set <= other
|
||||
|
||||
|
|
|
@ -102,6 +102,20 @@ class TestJointOps(unittest.TestCase):
|
|||
self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
|
||||
self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
|
||||
|
||||
def test_isdisjoint(self):
|
||||
def f(s1, s2):
|
||||
'Pure python equivalent of isdisjoint()'
|
||||
return not set(s1).intersection(s2)
|
||||
for larg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
|
||||
s1 = self.thetype(larg)
|
||||
for rarg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
|
||||
for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple:
|
||||
s2 = C(rarg)
|
||||
actual = s1.isdisjoint(s2)
|
||||
expected = f(s1, s2)
|
||||
self.assertEqual(actual, expected)
|
||||
self.assert_(actual is True or actual is False)
|
||||
|
||||
def test_and(self):
|
||||
i = self.s.intersection(self.otherword)
|
||||
self.assertEqual(self.s & set(self.otherword), i)
|
||||
|
@ -657,6 +671,18 @@ class TestBasicOps(unittest.TestCase):
|
|||
result = empty_set & self.set
|
||||
self.assertEqual(result, empty_set)
|
||||
|
||||
def test_self_isdisjoint(self):
|
||||
result = self.set.isdisjoint(self.set)
|
||||
self.assertEqual(result, not self.set)
|
||||
|
||||
def test_empty_isdisjoint(self):
|
||||
result = self.set.isdisjoint(empty_set)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
def test_isdisjoint_empty(self):
|
||||
result = empty_set.isdisjoint(self.set)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
def test_self_symmetric_difference(self):
|
||||
result = self.set ^ self.set
|
||||
self.assertEqual(result, empty_set)
|
||||
|
@ -835,6 +861,22 @@ class TestBinaryOps(unittest.TestCase):
|
|||
result = self.set & set([8])
|
||||
self.assertEqual(result, empty_set)
|
||||
|
||||
def test_isdisjoint_subset(self):
|
||||
result = self.set.isdisjoint(set((2, 4)))
|
||||
self.assertEqual(result, False)
|
||||
|
||||
def test_isdisjoint_superset(self):
|
||||
result = self.set.isdisjoint(set([2, 4, 6, 8]))
|
||||
self.assertEqual(result, False)
|
||||
|
||||
def test_isdisjoint_overlap(self):
|
||||
result = self.set.isdisjoint(set([3, 4, 5]))
|
||||
self.assertEqual(result, False)
|
||||
|
||||
def test_isdisjoint_non_overlap(self):
|
||||
result = self.set.isdisjoint(set([8]))
|
||||
self.assertEqual(result, True)
|
||||
|
||||
def test_sym_difference_subset(self):
|
||||
result = self.set ^ set((2, 4))
|
||||
self.assertEqual(result, set([6]))
|
||||
|
@ -1456,11 +1498,14 @@ class TestVariousIteratorArgs(unittest.TestCase):
|
|||
def test_inline_methods(self):
|
||||
s = set('november')
|
||||
for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'):
|
||||
for meth in (s.union, s.intersection, s.difference, s.symmetric_difference):
|
||||
for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
|
||||
for g in (G, I, Ig, L, R):
|
||||
expected = meth(data)
|
||||
actual = meth(G(data))
|
||||
self.assertEqual(sorted(actual), sorted(expected))
|
||||
if isinstance(expected, bool):
|
||||
self.assertEqual(actual, expected)
|
||||
else:
|
||||
self.assertEqual(sorted(actual), sorted(expected))
|
||||
self.assertRaises(TypeError, meth, X(s))
|
||||
self.assertRaises(TypeError, meth, N(s))
|
||||
self.assertRaises(ZeroDivisionError, meth, E(s))
|
||||
|
|
|
@ -12,6 +12,8 @@ What's New in Python 2.6 alpha 1?
|
|||
Core and builtins
|
||||
-----------------
|
||||
|
||||
- sets and frozensets now have an isdisjoint() method.
|
||||
|
||||
- optimize the performance of builtin.sum().
|
||||
|
||||
- Fix warnings found by the new version of the Coverity checker.
|
||||
|
|
|
@ -1332,6 +1332,72 @@ set_iand(PySetObject *so, PyObject *other)
|
|||
return (PyObject *)so;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
set_isdisjoint(PySetObject *so, PyObject *other)
|
||||
{
|
||||
PyObject *key, *it, *tmp;
|
||||
|
||||
if ((PyObject *)so == other) {
|
||||
if (PySet_GET_SIZE(so) == 0)
|
||||
Py_RETURN_TRUE;
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (PyAnySet_CheckExact(other)) {
|
||||
Py_ssize_t pos = 0;
|
||||
setentry *entry;
|
||||
|
||||
if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
|
||||
tmp = (PyObject *)so;
|
||||
so = (PySetObject *)other;
|
||||
other = tmp;
|
||||
}
|
||||
while (set_next((PySetObject *)other, &pos, &entry)) {
|
||||
int rv = set_contains_entry(so, entry);
|
||||
if (rv == -1)
|
||||
return NULL;
|
||||
if (rv)
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
|
||||
it = PyObject_GetIter(other);
|
||||
if (it == NULL)
|
||||
return NULL;
|
||||
|
||||
while ((key = PyIter_Next(it)) != NULL) {
|
||||
int rv;
|
||||
setentry entry;
|
||||
long hash = PyObject_Hash(key);
|
||||
|
||||
Py_DECREF(key);
|
||||
if (hash == -1) {
|
||||
Py_DECREF(it);
|
||||
return NULL;
|
||||
}
|
||||
entry.hash = hash;
|
||||
entry.key = key;
|
||||
rv = set_contains_entry(so, &entry);
|
||||
if (rv == -1) {
|
||||
Py_DECREF(it);
|
||||
return NULL;
|
||||
}
|
||||
if (rv) {
|
||||
Py_DECREF(it);
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
Py_DECREF(it);
|
||||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(isdisjoint_doc,
|
||||
"Return True if two sets have a null intersection.");
|
||||
|
||||
static int
|
||||
set_difference_update_internal(PySetObject *so, PyObject *other)
|
||||
{
|
||||
|
@ -1861,6 +1927,8 @@ static PyMethodDef set_methods[] = {
|
|||
intersection_doc},
|
||||
{"intersection_update",(PyCFunction)set_intersection_update, METH_O,
|
||||
intersection_update_doc},
|
||||
{"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
|
||||
isdisjoint_doc},
|
||||
{"issubset", (PyCFunction)set_issubset, METH_O,
|
||||
issubset_doc},
|
||||
{"issuperset", (PyCFunction)set_issuperset, METH_O,
|
||||
|
@ -1984,6 +2052,8 @@ static PyMethodDef frozenset_methods[] = {
|
|||
difference_doc},
|
||||
{"intersection",(PyCFunction)set_intersection, METH_O,
|
||||
intersection_doc},
|
||||
{"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
|
||||
isdisjoint_doc},
|
||||
{"issubset", (PyCFunction)set_issubset, METH_O,
|
||||
issubset_doc},
|
||||
{"issuperset", (PyCFunction)set_issuperset, METH_O,
|
||||
|
|
Loading…
Reference in New Issue