mirror of
https://github.com/python/cpython.git
synced 2025-08-31 05:58:33 +00:00
Implement, test and document "key in dict" and "key not in dict".
I know some people don't like this -- if it's really controversial, I'll take it out again. (If it's only Alex Martelli who doesn't like it, that doesn't count as "real controversial" though. :-) That's why this is a separate checkin from the iterators stuff I'm about to check in next.
This commit is contained in:
parent
78fe5308b4
commit
0dbb4fba4c
5 changed files with 59 additions and 8 deletions
|
@ -867,9 +867,15 @@ arbitrary objects):
|
|||
{(1)}
|
||||
\lineiii{\var{a}.clear()}{remove all items from \code{a}}{}
|
||||
\lineiii{\var{a}.copy()}{a (shallow) copy of \code{a}}{}
|
||||
\lineiii{\var{a}.has_key(\var{k})}
|
||||
\lineiii{\var{k} \code{in} \var{a}}
|
||||
{\code{1} if \var{a} has a key \var{k}, else \code{0}}
|
||||
{}
|
||||
\lineiii{\var{k} not in \var{a}}
|
||||
{\code{0} if \var{a} has a key \var{k}, else \code{1}}
|
||||
{}
|
||||
\lineiii{\var{a}.has_key(\var{k})}
|
||||
{Equivalent to \var{k} \code{in} \var{a}}
|
||||
{}
|
||||
\lineiii{\var{a}.items()}
|
||||
{a copy of \var{a}'s list of (\var{key}, \var{value}) pairs}
|
||||
{(2)}
|
||||
|
@ -879,11 +885,11 @@ arbitrary objects):
|
|||
{(3)}
|
||||
\lineiii{\var{a}.values()}{a copy of \var{a}'s list of values}{(2)}
|
||||
\lineiii{\var{a}.get(\var{k}\optional{, \var{x}})}
|
||||
{\code{\var{a}[\var{k}]} if \code{\var{a}.has_key(\var{k})},
|
||||
{\code{\var{a}[\var{k}]} if \code{\var{k} in \var{a}}},
|
||||
else \var{x}}
|
||||
{(4)}
|
||||
\lineiii{\var{a}.setdefault(\var{k}\optional{, \var{x}})}
|
||||
{\code{\var{a}[\var{k}]} if \code{\var{a}.has_key(\var{k})},
|
||||
{\code{\var{a}[\var{k}]} if \code{\var{k} in \var{a}}},
|
||||
else \var{x} (also setting it)}
|
||||
{(5)}
|
||||
\lineiii{\var{a}.popitem()}
|
||||
|
|
|
@ -1134,7 +1134,10 @@ multiplication (meaning repetition) by defining the methods
|
|||
\method{__add__()}, \method{__radd__()}, \method{__iadd__()},
|
||||
\method{__mul__()}, \method{__rmul__()} and \method{__imul__()} described
|
||||
below; they should not define \method{__coerce__()} or other numerical
|
||||
operators.
|
||||
operators. It is recommended that both mappings and sequences
|
||||
implement the \method{__contains__}, to allow efficient use of the
|
||||
\code{in} operator; for mappings, \code{in} should be equivalent of
|
||||
\method{has_key()}; for sequences, it should search through the values.
|
||||
\withsubitem{(mapping object method)}{
|
||||
\ttindex{keys()}
|
||||
\ttindex{values()}
|
||||
|
@ -1143,7 +1146,8 @@ operators.
|
|||
\ttindex{get()}
|
||||
\ttindex{clear()}
|
||||
\ttindex{copy()}
|
||||
\ttindex{update()}}
|
||||
\ttindex{update()}
|
||||
\ttindex{__contains__()}}
|
||||
\withsubitem{(sequence object method)}{
|
||||
\ttindex{append()}
|
||||
\ttindex{count()}
|
||||
|
@ -1158,7 +1162,8 @@ operators.
|
|||
\ttindex{__iadd__()}
|
||||
\ttindex{__mul__()}
|
||||
\ttindex{__rmul__()}
|
||||
\ttindex{__imul__()}}
|
||||
\ttindex{__imul__()}
|
||||
\ttindex{__contains__()}}
|
||||
\withsubitem{(numeric object method)}{\ttindex{__coerce__()}}
|
||||
|
||||
\begin{methoddesc}[mapping object]{__len__}{self}
|
||||
|
|
|
@ -768,7 +768,9 @@ not in \var{s}} returns the negation of \code{\var{x} in \var{s}}.
|
|||
The set membership test has traditionally been bound to sequences; an
|
||||
object is a member of a set if the set is a sequence and contains an
|
||||
element equal to that object. However, it is possible for an object
|
||||
to support membership tests without being a sequence.
|
||||
to support membership tests without being a sequence. In particular,
|
||||
dictionaries support memership testing as a nicer way of spelling
|
||||
\code{\var{key} in \var{dict}}; other mapping types may follow suit.
|
||||
|
||||
For the list and tuple types, \code{\var{x} in \var{y}} is true if and
|
||||
only if there exists an index \var{i} such that
|
||||
|
|
|
@ -221,6 +221,8 @@ print '6.6 Mappings == Dictionaries'
|
|||
d = {}
|
||||
if d.keys() != []: raise TestFailed, '{}.keys()'
|
||||
if d.has_key('a') != 0: raise TestFailed, '{}.has_key(\'a\')'
|
||||
if ('a' in d) != 0: raise TestFailed, "'a' in {}"
|
||||
if ('a' not in d) != 1: raise TestFailed, "'a' not in {}"
|
||||
if len(d) != 0: raise TestFailed, 'len({})'
|
||||
d = {'a': 1, 'b': 2}
|
||||
if len(d) != 2: raise TestFailed, 'len(dict)'
|
||||
|
@ -229,6 +231,8 @@ k.sort()
|
|||
if k != ['a', 'b']: raise TestFailed, 'dict keys()'
|
||||
if d.has_key('a') and d.has_key('b') and not d.has_key('c'): pass
|
||||
else: raise TestFailed, 'dict keys()'
|
||||
if 'a' in d and 'b' in d and 'c' not in d: pass
|
||||
else: raise TestFailed, 'dict keys() # in/not in version'
|
||||
if d['a'] != 1 or d['b'] != 2: raise TestFailed, 'dict item'
|
||||
d['c'] = 3
|
||||
d['a'] = 4
|
||||
|
|
|
@ -1292,6 +1292,40 @@ dict_getattr(dictobject *mp, char *name)
|
|||
return Py_FindMethod(mapp_methods, (PyObject *)mp, name);
|
||||
}
|
||||
|
||||
static int
|
||||
dict_contains(dictobject *mp, PyObject *key)
|
||||
{
|
||||
long hash;
|
||||
|
||||
#ifdef CACHE_HASH
|
||||
if (!PyString_Check(key) ||
|
||||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
|
||||
#endif
|
||||
{
|
||||
hash = PyObject_Hash(key);
|
||||
if (hash == -1)
|
||||
return -1;
|
||||
}
|
||||
return (mp->ma_size != 0
|
||||
&& (mp->ma_lookup)(mp, key, hash)->me_value != NULL);
|
||||
}
|
||||
|
||||
staticforward PyObject *dictiter_new(dictobject *);
|
||||
|
||||
/* Hack to implement "key in dict" */
|
||||
static PySequenceMethods dict_as_sequence = {
|
||||
0, /* sq_length */
|
||||
0, /* sq_concat */
|
||||
0, /* sq_repeat */
|
||||
0, /* sq_item */
|
||||
0, /* sq_slice */
|
||||
0, /* sq_ass_item */
|
||||
0, /* sq_ass_slice */
|
||||
(objobjproc)dict_contains, /* sq_contains */
|
||||
0, /* sq_inplace_concat */
|
||||
0, /* sq_inplace_repeat */
|
||||
};
|
||||
|
||||
PyTypeObject PyDict_Type = {
|
||||
PyObject_HEAD_INIT(&PyType_Type)
|
||||
0,
|
||||
|
@ -1305,7 +1339,7 @@ PyTypeObject PyDict_Type = {
|
|||
(cmpfunc)dict_compare, /* tp_compare */
|
||||
(reprfunc)dict_repr, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
&dict_as_sequence, /* tp_as_sequence */
|
||||
&dict_as_mapping, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue