Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e33d3df

Browse files
committed
SF Patch 643443. Added dict.fromkeys(iterable, value=None), a class
method for constructing new dictionaries from sequences of keys.
1 parent e9cfcef commit e33d3df

4 files changed

Lines changed: 97 additions & 1 deletion

File tree

Doc/lib/libstdtypes.tex

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1055,8 +1055,11 @@ \subsection{Mapping Types \label{typesmapping}}
10551055
{(3)}
10561056
\lineiii{\var{a}.keys()}{a copy of \var{a}'s list of keys}{(3)}
10571057
\lineiii{\var{a}.update(\var{b})}
1058-
{\code{for k in \var{b}.keys(): \var{a}[k] = \var{b}[k]}}
1058+
{\code{for \var{k} in \var{b}.keys(): \var{a}[\var{k}] = \var{b}[\var{k}]}}
10591059
{}
1060+
\lineiii{\var{a}.fromkeys(\var{seq}\optional{, \var{value}})}
1061+
{Creates a new dictionary with keys from \var{seq} and values set to \var{value}}
1062+
{(7)}
10601063
\lineiii{\var{a}.values()}{a copy of \var{a}'s list of values}{(3)}
10611064
\lineiii{\var{a}.get(\var{k}\optional{, \var{x}})}
10621065
{\code{\var{a}[\var{k}]} if \code{\var{k} in \var{a}},
@@ -1116,6 +1119,10 @@ \subsection{Mapping Types \label{typesmapping}}
11161119
over a dictionary, as often used in set algorithms.
11171120
\end{description}
11181121

1122+
\item[(7)] \function{fromkeys()} is a class method that returns a
1123+
new dictionary. \var{value} defaults to \code{None}. \versionadded{2.3}
1124+
\end{description}
1125+
11191126

11201127
\subsection{File Objects
11211128
\label{bltin-file-objects}}

Lib/test/test_types.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,34 @@ def __getitem__(self, key):
530530
try: d.update(FailingUserDict())
531531
except ValueError: pass
532532
else: raise TestFailed, 'dict.update(), __getitem__ expected ValueError'
533+
# dict.fromkeys()
534+
if dict.fromkeys('abc') != {'a':None, 'b':None, 'c':None}:
535+
raise TestFailed, 'dict.fromkeys did not work as a class method'
536+
d = {}
537+
if d.fromkeys('abc') is d:
538+
raise TestFailed, 'dict.fromkeys did not return a new dict'
539+
if d.fromkeys('abc') != {'a':None, 'b':None, 'c':None}:
540+
raise TestFailed, 'dict.fromkeys failed with default value'
541+
if d.fromkeys((4,5),0) != {4:0, 5:0}:
542+
raise TestFailed, 'dict.fromkeys failed with specified value'
543+
if d.fromkeys([]) != {}:
544+
raise TestFailed, 'dict.fromkeys failed with null sequence'
545+
def g():
546+
yield 1
547+
if d.fromkeys(g()) != {1:None}:
548+
raise TestFailed, 'dict.fromkeys failed with a generator'
549+
try: {}.fromkeys(3)
550+
except TypeError: pass
551+
else: raise TestFailed, 'dict.fromkeys failed to raise TypeError'
552+
class dictlike(dict): pass
553+
if dictlike.fromkeys('a') != {'a':None}:
554+
raise TestFailed, 'dictsubclass.fromkeys did not inherit'
555+
if dictlike().fromkeys('a') != {'a':None}:
556+
raise TestFailed, 'dictsubclass.fromkeys did not inherit'
557+
if type(dictlike.fromkeys('a')) is not dictlike:
558+
raise TestFailed, 'dictsubclass.fromkeys created wrong type'
559+
if type(dictlike().fromkeys('a')) is not dictlike:
560+
raise TestFailed, 'dictsubclass.fromkeys created wrong type'
533561
# dict.copy()
534562
d = {1:1, 2:2, 3:3}
535563
if d.copy() != {1:1, 2:2, 3:3}: raise TestFailed, 'dict copy'

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,11 @@ Core and builtins
270270
an optional argument that specifies the characters to strip. For
271271
example, "Foo!!!?!?!?".rstrip("?!") -> "Foo".
272272

273+
- Dictionaries have a new class method, fromkeys(iterable, value=None).
274+
It constructs a new dictionary with keys taken from the iterable and
275+
all values set to a single value. It is used for building membership
276+
tests and for removing duplicates from sequences.
277+
273278
- Added a new dict method pop(key). This removes and returns the
274279
value corresponding to key. [SF patch #539949]
275280

Objects/dictobject.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,56 @@ dict_items(register dictobject *mp)
962962
return v;
963963
}
964964

965+
static PyObject *
966+
dict_fromkeys(PyObject *mp, PyObject *args)
967+
{
968+
PyObject *seq;
969+
PyObject *value = Py_None;
970+
PyObject *it; /* iter(seq) */
971+
PyObject *key;
972+
PyObject *d;
973+
PyObject *cls;
974+
int status;
975+
976+
if (!PyArg_ParseTuple(args, "OO|O:fromkeys", &cls, &seq, &value))
977+
return NULL;
978+
979+
d = PyObject_CallObject(cls, NULL);
980+
if (d == NULL)
981+
return NULL;
982+
if (!PyDict_Check(d)) {
983+
PyErr_BadInternalCall();
984+
return NULL;
985+
}
986+
987+
it = PyObject_GetIter(seq);
988+
if (it == NULL){
989+
Py_DECREF(d);
990+
return NULL;
991+
}
992+
993+
for (;;) {
994+
key = PyIter_Next(it);
995+
if (key == NULL) {
996+
if (PyErr_Occurred())
997+
goto Fail;
998+
break;
999+
}
1000+
status = PyDict_SetItem(d, key, value);
1001+
Py_DECREF(key);
1002+
if (status < 0)
1003+
goto Fail;
1004+
}
1005+
1006+
Py_DECREF(it);
1007+
return d;
1008+
1009+
Fail:
1010+
Py_DECREF(it);
1011+
Py_DECREF(d);
1012+
return NULL;
1013+
}
1014+
9651015
static PyObject *
9661016
dict_update(PyObject *mp, PyObject *other)
9671017
{
@@ -1682,6 +1732,10 @@ PyDoc_STRVAR(values__doc__,
16821732
PyDoc_STRVAR(update__doc__,
16831733
"D.update(E) -> None. Update D from E: for k in E.keys(): D[k] = E[k]");
16841734

1735+
PyDoc_STRVAR(fromkeys__doc__,
1736+
"dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.\n\
1737+
v defaults to None.");
1738+
16851739
PyDoc_STRVAR(clear__doc__,
16861740
"D.clear() -> None. Remove all items from D.");
16871741

@@ -1716,6 +1770,8 @@ static PyMethodDef mapp_methods[] = {
17161770
values__doc__},
17171771
{"update", (PyCFunction)dict_update, METH_O,
17181772
update__doc__},
1773+
{"fromkeys", (PyCFunction)dict_fromkeys, METH_VARARGS | METH_CLASS,
1774+
fromkeys__doc__},
17191775
{"clear", (PyCFunction)dict_clear, METH_NOARGS,
17201776
clear__doc__},
17211777
{"copy", (PyCFunction)dict_copy, METH_NOARGS,

0 commit comments

Comments
 (0)