Use dictionary specific looping idiom where possible.

Simplifies and speeds-up the code.
This commit is contained in:
Raymond Hettinger 2003-12-13 14:46:46 +00:00
parent 0c66967e3d
commit dc5ae11abf

View file

@ -369,7 +369,9 @@ static PyObject *
set_difference(PySetObject *so, PyObject *other) set_difference(PySetObject *so, PyObject *other)
{ {
PySetObject *result, *otherset=NULL; PySetObject *result, *otherset=NULL;
PyObject *item, *otherdata, *tgtdata, *it; PyObject *otherdata, *tgtdata;
PyObject *key, *value;
int pos = 0;
result = (PySetObject *)make_new_set(so->ob_type, NULL); result = (PySetObject *)make_new_set(so->ob_type, NULL);
if (result == NULL) if (result == NULL)
@ -389,30 +391,15 @@ set_difference(PySetObject *so, PyObject *other)
otherdata = otherset->data; otherdata = otherset->data;
} }
it = PyObject_GetIter(so->data); while (PyDict_Next(so->data, &pos, &key, &value)) {
if (it == NULL) { if (!PyDict_Contains(otherdata, key)) {
Py_XDECREF(otherset); if (PyDict_SetItem(tgtdata, key, Py_True) == -1) {
Py_DECREF(result);
return NULL;
}
while ((item = PyIter_Next(it)) != NULL) {
if (!PyDict_Contains(otherdata, item)) {
if (PyDict_SetItem(tgtdata, item, Py_True) == -1) {
Py_XDECREF(otherset); Py_XDECREF(otherset);
Py_DECREF(it);
Py_DECREF(item);
return NULL; return NULL;
} }
} }
Py_DECREF(item);
} }
Py_DECREF(it);
Py_XDECREF(otherset); Py_XDECREF(otherset);
if (PyErr_Occurred()) {
Py_DECREF(result);
return NULL;
}
return (PyObject *)result; return (PyObject *)result;
} }
@ -482,11 +469,12 @@ set_isub(PySetObject *so, PyObject *other)
static PyObject * static PyObject *
set_symmetric_difference_update(PySetObject *so, PyObject *other) set_symmetric_difference_update(PySetObject *so, PyObject *other)
{ {
PyObject *item, *selfdata, *it, *otherdata; PyObject *selfdata, *otherdata;
PySetObject *otherset = NULL; PySetObject *otherset = NULL;
PyObject *key, *value;
int pos = 0;
selfdata = so->data; selfdata = so->data;
if (PyDict_Check(other)) if (PyDict_Check(other))
otherdata = other; otherdata = other;
else if (PyAnySet_Check(other)) else if (PyAnySet_Check(other))
@ -498,32 +486,20 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other)
otherdata = otherset->data; otherdata = otherset->data;
} }
it = PyObject_GetIter(otherdata); while (PyDict_Next(otherdata, &pos, &key, &value)) {
if (it == NULL) if (PyDict_Contains(selfdata, key)) {
return NULL; if (PyDict_DelItem(selfdata, key) == -1) {
while ((item = PyIter_Next(it)) != NULL) {
if (PyDict_Contains(selfdata, item)) {
if (PyDict_DelItem(selfdata, item) == -1) {
Py_XDECREF(otherset); Py_XDECREF(otherset);
Py_DECREF(it);
Py_DECREF(item);
return NULL; return NULL;
} }
} else { } else {
if (PyDict_SetItem(selfdata, item, Py_True) == -1) { if (PyDict_SetItem(selfdata, key, Py_True) == -1) {
Py_XDECREF(otherset); Py_XDECREF(otherset);
Py_DECREF(it);
Py_DECREF(item);
return NULL; return NULL;
} }
} }
Py_DECREF(item);
} }
Py_XDECREF(otherset); Py_XDECREF(otherset);
Py_DECREF(it);
if (PyErr_Occurred())
return NULL;
Py_RETURN_NONE; Py_RETURN_NONE;
} }
@ -534,7 +510,9 @@ static PyObject *
set_symmetric_difference(PySetObject *so, PyObject *other) set_symmetric_difference(PySetObject *so, PyObject *other)
{ {
PySetObject *result; PySetObject *result;
PyObject *item, *selfdata, *otherdata, *tgtdata, *it, *rv, *otherset; PyObject *selfdata, *otherdata, *tgtdata, *rv, *otherset;
PyObject *key, *value;
int pos = 0;
if (PyDict_Check(other)) if (PyDict_Check(other))
otherdata = other; otherdata = other;
@ -557,46 +535,23 @@ set_symmetric_difference(PySetObject *so, PyObject *other)
tgtdata = result->data; tgtdata = result->data;
selfdata = so->data; selfdata = so->data;
it = PyObject_GetIter(otherdata); while (PyDict_Next(otherdata, &pos, &key, &value)) {
if (it == NULL) { if (!PyDict_Contains(selfdata, key)) {
Py_DECREF(result); if (PyDict_SetItem(tgtdata, key, Py_True) == -1) {
return NULL; Py_DECREF(result);
}
while ((item = PyIter_Next(it)) != NULL) {
if (!PyDict_Contains(selfdata, item)) {
if (PyDict_SetItem(tgtdata, item, Py_True) == -1) {
Py_DECREF(it);
Py_DECREF(item);
return NULL; return NULL;
} }
} }
Py_DECREF(item);
}
Py_DECREF(it);
if (PyErr_Occurred()) {
Py_DECREF(result);
return NULL;
} }
it = PyObject_GetIter(selfdata); pos = 0;
if (it == NULL) { while (PyDict_Next(selfdata, &pos, &key, &value)) {
Py_DECREF(result); if (!PyDict_Contains(otherdata, key)) {
return NULL; if (PyDict_SetItem(tgtdata, key, Py_True) == -1) {
} Py_DECREF(result);
while ((item = PyIter_Next(it)) != NULL) {
if (!PyDict_Contains(otherdata, item)) {
if (PyDict_SetItem(tgtdata, item, Py_True) == -1) {
Py_DECREF(it);
Py_DECREF(item);
return NULL; return NULL;
} }
} }
Py_DECREF(item);
}
Py_DECREF(it);
if (PyErr_Occurred()) {
Py_DECREF(result);
return NULL;
} }
return (PyObject *)result; return (PyObject *)result;
@ -637,7 +592,9 @@ set_ixor(PySetObject *so, PyObject *other)
static PyObject * static PyObject *
set_issubset(PySetObject *so, PyObject *other) set_issubset(PySetObject *so, PyObject *other)
{ {
PyObject *otherdata, *it, *item, *tmp, *result; PyObject *otherdata, *tmp, *result;
PyObject *key, *value;
int pos = 0;
if (!PyAnySet_Check(other)) { if (!PyAnySet_Check(other)) {
tmp = make_new_set(&PySet_Type, other); tmp = make_new_set(&PySet_Type, other);
@ -649,23 +606,12 @@ set_issubset(PySetObject *so, PyObject *other)
} }
if (set_len(so) > set_len((PySetObject *)other)) if (set_len(so) > set_len((PySetObject *)other))
Py_RETURN_FALSE; Py_RETURN_FALSE;
it = PyObject_GetIter(so->data);
if (it == NULL)
return NULL;
otherdata = ((PySetObject *)other)->data; otherdata = ((PySetObject *)other)->data;
while ((item = PyIter_Next(it)) != NULL) { while (PyDict_Next(((PySetObject *)so)->data, &pos, &key, &value)) {
if (!PyDict_Contains(otherdata, item)) { if (!PyDict_Contains(otherdata, key))
Py_DECREF(it);
Py_DECREF(item);
Py_RETURN_FALSE; Py_RETURN_FALSE;
}
Py_DECREF(item);
} }
Py_DECREF(it);
if (PyErr_Occurred())
return NULL;
Py_RETURN_TRUE; Py_RETURN_TRUE;
} }
@ -706,29 +652,22 @@ set_nocmp(PyObject *self)
static long static long
frozenset_hash(PyObject *self) frozenset_hash(PyObject *self)
{ {
PyObject *it, *item;
PySetObject *so = (PySetObject *)self; PySetObject *so = (PySetObject *)self;
long hash = 0; PyObject *key, *value;
int pos = 0;
long hash = 0;
if (so->hash != -1) if (so->hash != -1)
return so->hash; return so->hash;
it = PyObject_GetIter(((PySetObject *)so)->data);
if (it == NULL)
return -1;
while ((item = PyIter_Next(it)) != NULL) { while (PyDict_Next(so->data, &pos, &key, &value)) {
/* Multiplying by a large prime increases the bit dispersion for /* Multiplying by a large prime increases the bit dispersion for
closely spaced hash values. The is important because some closely spaced hash values. The is important because some
use cases have many combinations of a small number of use cases have many combinations of a small number of
elements with nearby hashes so that many distinct combinations elements with nearby hashes so that many distinct combinations
collapse to only a handful of distinct hash values. */ collapse to only a handful of distinct hash values. */
hash ^= PyObject_Hash(item) * 3644798167u; hash ^= PyObject_Hash(key) * 3644798167u;
Py_DECREF(item);
} }
Py_DECREF(it);
if (PyErr_Occurred())
return -1;
so->hash = hash; so->hash = hash;
return hash; return hash;
} }
@ -788,30 +727,17 @@ set_repr(PySetObject *so)
static int static int
set_tp_print(PySetObject *so, FILE *fp, int flags) set_tp_print(PySetObject *so, FILE *fp, int flags)
{ {
PyObject *it, *item; PyObject *key, *value;
int firstpass=1; int pos = 0;
it = PyObject_GetIter(so->data);
if (it == NULL)
return -1;
fprintf(fp, "%s([", so->ob_type->tp_name); fprintf(fp, "%s([", so->ob_type->tp_name);
while (PyDict_Next(so->data, &pos, &key, &value)) {
while ((item = PyIter_Next(it)) != NULL) { if (pos)
if (firstpass == 1)
firstpass = 0;
else
fprintf(fp, ", "); fprintf(fp, ", ");
if (PyObject_Print(item, fp, 0) != 0) { if (PyObject_Print(key, fp, 0) != 0)
Py_DECREF(it);
Py_DECREF(item);
return -1; return -1;
}
Py_DECREF(item);
} }
Py_DECREF(it);
fprintf(fp, "])"); fprintf(fp, "])");
if (PyErr_Occurred())
return -1;
return 0; return 0;
} }