84: #line 1129 "mxTools.pak"
85:
86: def tuples(*sequence):
87: if len(sequence) == 1: sequence = sequence[0]
88: m = len(sequence[0])
89: result = apply(map,(None,)+sequence)[:m]
90: print 'tuples'+`sequence`+'='+`result`
91: return result
959: #line 1137 "mxTools.pak"
960:
961: Py_C_Function( mxTools_tuples,
962: "tuples(sequence)\n\n"
963: "Returns a list much like apply(map,(None,)+tuple(sequence)))\n"
964: "does. Only with a bit more intuitive name. This function does\n"
965: "not optimize for the case where the sequences are of different\n"
966: "size and the resulting list of tuples will always\n"
967: "have the length of the first sequence. Missing entries\n"
968: "from the other sequences are filled in with None."
969: )
970: {
971: int n,m;
972: register int i;
973: register int j;
974: PyObject *l = 0;
975: PyObject *arg,*w;
976:
977: Py_GetArgObject(arg);
978:
979: /* Get tuple size (m) */
980: m = PySequence_Length(arg);
981: Py_Assert(m > 0,
982: PyExc_TypeError,
983: "sequence must have at least one element");
984:
985: /* Get list size (n) */
986: w = PySequence_GetItem(arg,0);
987: if (!w)
988: goto onError;
989: n = PySequence_Length(w);
990: Py_DECREF(w);
991: Py_Assert(n >= 0,
992: PyExc_TypeError,
993: "sequence elements must be sequences");
994:
995: /* XXX Could speed this up by rearranging and joining the loops */
996:
997: /* Create list of tuples */
998: l = PyList_New(n);
999: if (!l)
1000: goto onError;
1001: for (j = 0; j < n; j++) {
1002: PyObject *v;
1003:
1004: v = PyTuple_New(m);
1005: if (!v)
1006: goto onError;
1007: PyList_SET_ITEM(l,j,v);
1008: }
1009:
1010: /* Fill them in */
1011: for (i = 0; i < m; i++) {
1012: PyObject *u;
1013:
1014: u = PySequence_GetItem(arg,i);
1015: if (!u)
1016: goto onError;
1017:
1018: for (j = 0; j < n; j++) {
1019: PyObject *v;
1020:
1021: v = PySequence_GetItem(u,j);
1022: if (!v) {
1023: if (PyErr_ExceptionMatches(PyExc_IndexError)) {
1024: PyErr_Clear();
1025: /* Fill up the rest with None */
1026: for (; j < n; j++) {
1027: Py_INCREF(Py_None);
1028: PyTuple_SET_ITEM(PyList_GET_ITEM(l,j),i,Py_None);
1029: }
1030: break;
1031: }
1032: else {
1033: Py_DECREF(u);
1034: goto onError;
1035: }
1036: }
1037: PyTuple_SET_ITEM(PyList_GET_ITEM(l,j),i,v);
1038: }
1039: Py_DECREF(u);
1040: }
1041: return l;
1042:
1043: onError:
1044: Py_XDECREF(l);
1045: return NULL;
1046: }
1047: