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

Skip to content

Commit 5a65c2d

Browse files
author
Peter Schneider-Kamp
committed
added count, extend, index, pop and remove to arraymodule
1 parent 4640e13 commit 5a65c2d

4 files changed

Lines changed: 233 additions & 74 deletions

File tree

Doc/lib/libarray.tex

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ \section{\module{array} ---
8383
data from a file written on a machine with a different byte order.
8484
\end{methoddesc}
8585

86+
\begin{methoddesc}[array]{count}{x}
87+
Return the number of occurences of \var{x} in the array.
88+
\end{methoddesc}
89+
90+
\begin{methoddesc}[array]{extend}{a}
91+
Append array items from \var{a} to the end of the array.
92+
\end{methoddesc}
93+
8694
\begin{methoddesc}[array]{fromfile}{f, n}
8795
Read \var{n} items (as machine values) from the file object \var{f}
8896
and append them to the end of the array. If less than \var{n} items
@@ -104,11 +112,22 @@ \section{\module{array} ---
104112
file using the \method{fromfile()} method).
105113
\end{methoddesc}
106114

115+
\begin{methoddesc}[array]{index}{x}
116+
Return the smallest \var{i} such that \var{i} is the index of
117+
the first occurence of \var{x} in the array.
118+
\end{methoddesc}
119+
107120
\begin{methoddesc}[array]{insert}{i, x}
108121
Insert a new item with value \var{x} in the array before position
109122
\var{i}.
110123
\end{methoddesc}
111124

125+
\begin{methoddesc}[array]{pop}{\optional{i}}
126+
Removes the item with the index \var{i} from the array and returns
127+
it. The optional argument defaults to \code{-1}, so that by default
128+
the last item is removed and returned.
129+
\end{methoddesc}
130+
112131
\begin{methoddesc}[array]{read}{f, n}
113132
\deprecated {1.5.1}
114133
{Use the \method{fromfile()} method.}
@@ -120,6 +139,10 @@ \section{\module{array} ---
120139
do.
121140
\end{methoddesc}
122141

142+
\begin{methoddesc}[array]{remove}{x}
143+
Remove the first occurence of \var{x} from the array.
144+
\end{methoddesc}
145+
123146
\begin{methoddesc}[array]{reverse}{}
124147
Reverse the order of the items in the array.
125148
\end{methoddesc}

Doc/lib/libstdtypes.tex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -506,8 +506,8 @@ \subsubsection{Mutable Sequence Types \label{typesseq-mutable}}
506506
\item[(3)] Raises \exception{ValueError} when \var{x} is not found in
507507
\var{s}.
508508

509-
\item[(4)] The \method{pop()} method is experimental and not supported
510-
by other mutable sequence types than lists. The optional argument
509+
\item[(4)] The \method{pop()} method is experimental and at the moment
510+
only supported by the list and array types. The optional argument
511511
\var{i} defaults to \code{-1}, so that by default the last item is
512512
removed and returned.
513513

Lib/test/test_array.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,26 @@ def testtype(type, example):
105105
a[1:-1] = a
106106
if a != array.array(type, "aabcdee"):
107107
raise TestFailed, "array(%s) self-slice-assign (cntr)" % `type`
108+
if a.index("e") != 5:
109+
raise TestFailed, "array(%s) index-test" % `type`
110+
if a.count("a") != 2:
111+
raise TestFailed, "array(%s) count-test" % `type`
112+
a.remove("e")
113+
if a != array.array(type, "aabcde"):
114+
raise TestFailed, "array(%s) remove-test" % `type`
115+
if a.pop(0) != "a":
116+
raise TestFailed, "array(%s) pop-test" % `type`
117+
if a.pop(1) != "b":
118+
raise TestFailed, "array(%s) pop-test" % `type`
119+
a.extend(array.array(type, "xyz"))
120+
if a != array.array(type, "acdexyz"):
121+
raise TestFailed, "array(%s) extend-test" % `type`
122+
a.pop()
123+
a.pop()
124+
a.pop()
125+
a.pop()
126+
if a != array.array(type, "acd"):
127+
raise TestFailed, "array(%s) pop-test" % `type`
108128
else:
109129
a = array.array(type, [1, 2, 3, 4, 5])
110130
a[:-1] = a
@@ -118,6 +138,26 @@ def testtype(type, example):
118138
a[1:-1] = a
119139
if a != array.array(type, [1, 1, 2, 3, 4, 5, 5]):
120140
raise TestFailed, "array(%s) self-slice-assign (cntr)" % `type`
141+
if a.index(5) != 5:
142+
raise TestFailed, "array(%s) index-test" % `type`
143+
if a.count(1) != 2:
144+
raise TestFailed, "array(%s) count-test" % `type`
145+
a.remove(5)
146+
if a != array.array(type, [1, 1, 2, 3, 4, 5]):
147+
raise TestFailed, "array(%s) remove-test" % `type`
148+
if a.pop(0) != 1:
149+
raise TestFailed, "array(%s) pop-test" % `type`
150+
if a.pop(1) != 2:
151+
raise TestFailed, "array(%s) pop-test" % `type`
152+
a.extend(array.array(type, [7, 8, 9]))
153+
if a != array.array(type, [1, 3, 4, 5, 7, 8, 9]):
154+
raise TestFailed, "array(%s) extend-test" % `type`
155+
a.pop()
156+
a.pop()
157+
a.pop()
158+
a.pop()
159+
if a != array.array(type, [1, 3, 4]):
160+
raise TestFailed, "array(%s) pop-test" % `type`
121161

122162
# test that overflow exceptions are raised as expected for assignment
123163
# to array of specific integral types

Modules/arraymodule.c

Lines changed: 168 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,163 @@ ins(arrayobject *self, int where, PyObject *v)
673673
return Py_None;
674674
}
675675

676+
static PyObject *
677+
array_count(arrayobject *self, PyObject *args)
678+
{
679+
int count = 0;
680+
int i;
681+
PyObject *v;
682+
683+
if (!PyArg_ParseTuple(args, "O:count", &v))
684+
return NULL;
685+
for (i = 0; i < self->ob_size; i++) {
686+
PyObject *selfi = getarrayitem((PyObject *)self, i);
687+
if (PyObject_Compare(selfi, v) == 0)
688+
count++;
689+
Py_DECREF(selfi);
690+
if (PyErr_Occurred())
691+
return NULL;
692+
}
693+
return PyInt_FromLong((long)count);
694+
}
695+
696+
static char count_doc [] =
697+
"count (x)\n\
698+
\n\
699+
Return number of occurences of x in the array.";
700+
701+
static PyObject *
702+
array_index(arrayobject *self, PyObject *args)
703+
{
704+
int i;
705+
PyObject *v;
706+
707+
if (!PyArg_ParseTuple(args, "O:index", &v))
708+
return NULL;
709+
for (i = 0; i < self->ob_size; i++) {
710+
PyObject *selfi = getarrayitem((PyObject *)self, i);
711+
if (PyObject_Compare(selfi, v) == 0) {
712+
Py_DECREF(selfi);
713+
return PyInt_FromLong((long)i);
714+
}
715+
Py_DECREF(selfi);
716+
if (PyErr_Occurred())
717+
return NULL;
718+
}
719+
PyErr_SetString(PyExc_ValueError, "array.index(x): x not in list");
720+
return NULL;
721+
}
722+
723+
static char index_doc [] =
724+
"index (x)\n\
725+
\n\
726+
Return index of first occurence of x in the array.";
727+
728+
static PyObject *
729+
array_remove(arrayobject *self, PyObject *args)
730+
{
731+
int i;
732+
PyObject *v;
733+
734+
if (!PyArg_ParseTuple(args, "O:remove", &v))
735+
return NULL;
736+
for (i = 0; i < self->ob_size; i++) {
737+
PyObject *selfi = getarrayitem((PyObject *)self,i);
738+
if (PyObject_Compare(selfi, v) == 0) {
739+
Py_DECREF(selfi);
740+
if (array_ass_slice(self, i, i+1,
741+
(PyObject *)NULL) != 0)
742+
return NULL;
743+
Py_INCREF(Py_None);
744+
return Py_None;
745+
}
746+
Py_DECREF(selfi);
747+
if (PyErr_Occurred())
748+
return NULL;
749+
}
750+
PyErr_SetString(PyExc_ValueError, "array.remove(x): x not in list");
751+
return NULL;
752+
}
753+
754+
static char remove_doc [] =
755+
"remove (x)\n\
756+
\n\
757+
Remove the first occurence of x in the array.";
758+
759+
static PyObject *
760+
array_pop(arrayobject *self, PyObject *args)
761+
{
762+
int i = -1;
763+
PyObject *v;
764+
if (!PyArg_ParseTuple(args, "|i:pop", &i))
765+
return NULL;
766+
if (self->ob_size == 0) {
767+
/* Special-case most common failure cause */
768+
PyErr_SetString(PyExc_IndexError, "pop from empty array");
769+
return NULL;
770+
}
771+
if (i < 0)
772+
i += self->ob_size;
773+
if (i < 0 || i >= self->ob_size) {
774+
PyErr_SetString(PyExc_IndexError, "pop index out of range");
775+
return NULL;
776+
}
777+
v = getarrayitem((PyObject *)self,i);
778+
if (array_ass_slice(self, i, i+1, (PyObject *)NULL) != 0) {
779+
Py_DECREF(v);
780+
return NULL;
781+
}
782+
return v;
783+
}
784+
785+
static char pop_doc [] =
786+
"pop ([i])\n\
787+
\n\
788+
Return the i-th element and delete it from the array. i defaults to -1.";
789+
790+
static PyObject *
791+
array_extend(self, args)
792+
arrayobject *self;
793+
PyObject *args;
794+
{
795+
int size;
796+
PyObject *bb;
797+
arrayobject *np;
798+
799+
if (!PyArg_ParseTuple(args, "O:extend", &bb))
800+
return NULL;
801+
802+
if (!is_arrayobject(bb)) {
803+
PyErr_Format(PyExc_TypeError,
804+
"can only append array (not \"%.200s\") to array",
805+
bb->ob_type->tp_name);
806+
return NULL;
807+
}
808+
#define b ((arrayobject *)bb)
809+
if (self->ob_descr != b->ob_descr) {
810+
PyErr_SetString(PyExc_TypeError,
811+
"can only append arrays of same kind");
812+
return NULL;
813+
}
814+
size = self->ob_size + b->ob_size;
815+
PyMem_RESIZE(self->ob_item, char, size*self->ob_descr->itemsize);
816+
if (self->ob_item == NULL) {
817+
PyObject_Del(self);
818+
return PyErr_NoMemory();
819+
}
820+
memcpy(self->ob_item + self->ob_size*self->ob_descr->itemsize,
821+
b->ob_item, b->ob_size*b->ob_descr->itemsize);
822+
self->ob_size = size;
823+
Py_INCREF(Py_None);
824+
return Py_None;
825+
#undef b
826+
}
827+
828+
static char extend_doc [] =
829+
"extend(array)\n\
830+
\n\
831+
Append array items to the end of the array.";
832+
676833
static PyObject *
677834
array_insert(arrayobject *self, PyObject *args)
678835
{
@@ -816,74 +973,6 @@ static char reverse_doc [] =
816973
\n\
817974
Reverse the order of the items in the array.";
818975

819-
/* The following routines were adapted from listobject.c but not converted.
820-
To make them work you will have to work! */
821-
822-
#if 0
823-
static PyObject *
824-
array_index(arrayobject *self, PyObject *args)
825-
{
826-
int i;
827-
828-
if (args == NULL) {
829-
PyErr_BadArgument();
830-
return NULL;
831-
}
832-
for (i = 0; i < self->ob_size; i++) {
833-
if (PyObject_Compare(self->ob_item[i], args) == 0)
834-
return PyInt_FromLong((long)i);
835-
/* XXX PyErr_Occurred */
836-
}
837-
PyErr_SetString(PyExc_ValueError, "array.index(x): x not in array");
838-
return NULL;
839-
}
840-
#endif
841-
842-
#if 0
843-
static PyObject *
844-
array_count(arrayobject *self, PyObject *args)
845-
{
846-
int count = 0;
847-
int i;
848-
849-
if (args == NULL) {
850-
PyErr_BadArgument();
851-
return NULL;
852-
}
853-
for (i = 0; i < self->ob_size; i++) {
854-
if (PyObject_Compare(self->ob_item[i], args) == 0)
855-
count++;
856-
/* XXX PyErr_Occurred */
857-
}
858-
return PyInt_FromLong((long)count);
859-
}
860-
#endif
861-
862-
#if 0
863-
static PyObject *
864-
array_remove(arrayobject *self, PyObject *args)
865-
{
866-
int i;
867-
868-
if (args == NULL) {
869-
PyErr_BadArgument();
870-
return NULL;
871-
}
872-
for (i = 0; i < self->ob_size; i++) {
873-
if (PyObject_Compare(self->ob_item[i], args) == 0) {
874-
if (array_ass_slice(self, i, i+1,
875-
(PyObject *)NULL) != 0)
876-
return NULL;
877-
Py_INCREF(Py_None);
878-
return Py_None;
879-
}
880-
/* XXX PyErr_Occurred */
881-
}
882-
PyErr_SetString(PyExc_ValueError, "array.remove(x): x not in array");
883-
return NULL;
884-
}
885-
#endif
886-
887976
static PyObject *
888977
array_fromfile(arrayobject *self, PyObject *args)
889978
{
@@ -1095,16 +1184,18 @@ PyMethodDef array_methods[] = {
10951184
{"buffer_info", (PyCFunction)array_buffer_info, 0, buffer_info_doc},
10961185
{"byteswap", (PyCFunction)array_byteswap, METH_VARARGS,
10971186
byteswap_doc},
1098-
/* {"count", (method)array_count},*/
1187+
{"count", (PyCFunction)array_count, 1, count_doc},
1188+
{"extend", (PyCFunction)array_extend, 1, extend_doc},
10991189
{"fromfile", (PyCFunction)array_fromfile, 0, fromfile_doc},
11001190
{"fromlist", (PyCFunction)array_fromlist, 0, fromlist_doc},
11011191
{"fromstring", (PyCFunction)array_fromstring, 0, fromstring_doc},
1102-
/* {"index", (method)array_index},*/
1192+
{"index", (PyCFunction)array_index, 1, index_doc},
11031193
{"insert", (PyCFunction)array_insert, 0, insert_doc},
1194+
{"pop", (PyCFunction)array_pop, 1, pop_doc},
11041195
{"read", (PyCFunction)array_fromfile, 0, fromfile_doc},
1105-
/* {"remove", (method)array_remove},*/
1196+
{"remove", (PyCFunction)array_remove, 1, remove_doc},
11061197
{"reverse", (PyCFunction)array_reverse, 0, reverse_doc},
1107-
/* {"sort", (method)array_sort},*/
1198+
/* {"sort", (PyCFunction)array_sort, 0, sort_doc},*/
11081199
{"tofile", (PyCFunction)array_tofile, 0, tofile_doc},
11091200
{"tolist", (PyCFunction)array_tolist, 0, tolist_doc},
11101201
{"tostring", (PyCFunction)array_tostring, 0, tostring_doc},
@@ -1364,11 +1455,16 @@ Methods:\n\
13641455
append() -- append a new item to the end of the array\n\
13651456
buffer_info() -- return information giving the current memory info\n\
13661457
byteswap() -- byteswap all the items of the array\n\
1458+
count() -- return number of occurences of an object\n\
1459+
extend() -- extend array by appending array elements\n\
13671460
fromfile() -- read items from a file object\n\
13681461
fromlist() -- append items from the list\n\
13691462
fromstring() -- append items from the string\n\
1463+
index() -- return index of first occurence of an object\n\
13701464
insert() -- insert a new item into the array at a provided position\n\
1465+
pop() -- remove and return item (default last)\n\
13711466
read() -- DEPRECATED, use fromfile()\n\
1467+
remove() -- remove first occurence of an object\n\
13721468
reverse() -- reverse the order of the items in the array\n\
13731469
tofile() -- write all items to a file object\n\
13741470
tolist() -- return the array converted to an ordinary list\n\

0 commit comments

Comments
 (0)