Hola a todos,
Hace tiempo escribí esto, igual te sirve aunque falta pulirlo.
Saludos.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
class Vector(list):
'''Vector de tamaño fijo con/sin comprobación de tipo'''
def __new__(cls, *args, **kwargs):
# Internamente los elementos del vector se almacenan en una lista.
return list.__new__(cls, *args, **kwargs)
def __init__(self, length, default_value=None, initial_values=None,
typed=True):
# El vector tendrá el tamaño indicado por length.
# Los elementos del vector se inicializan con los elementos de
initial_values.
# Si len(initial_values) < length el vector se rellena con
default_value
# hasta alcanzar la longitud requerida.
# Si len(initial_values) > length se descartan los elementos de
initial_values
# con indice mayor a length.
# Si todos los elementos de initial_values y default_value
tienen el mismo
# tipo el vector será de dicho tipo y solo podra almacenar
valores de
# ese tipo. En caso contrario el vector no tendra tipo y podra
almacenar
# elementos de cualquier tipo.
# Si typed == False no se tendra en cuenta el tipo de los
elementos.
try:
same_type = True
l = len(initial_values)
for i in range(length):
if i < l:
self.append(initial_values[i])
same_type = same_type and (type(default_value) ==
type(initial_values[i]))
else:
self.append(default_value)
except:
self.extend([default_value]* length)
finally:
self.__length = length
self.__type = type(default_value) if (same_type and typed)
else type(None)
def __setitem__(self, index, value):
# Comprobamos el tipo antes de insertar un elemento.
if self.__type == type(value) or self.__type == type(None):
super(Vector, self).__setitem__(index, value)
else:
# Elemento de tipo incorrecto, no se inserta.
raise ValueError
def __setslice__(self, i, j, sequence):
# Impedimos este método para que altere el tamaño del vector.
# TODO: hacer lo mismo con el resto de métodos de la clase list que
# pueden cambiar el tamaño del vector.
raise ValueError # FIXME: poner la excepción correcta.
def __count__(self):
return self.__length
@property
def type(self):
return self.__type
@property
def length(self):
return self.__length
class Matrix(Vector):
'''Matriz bidimensional de tamaño fijo con/sin comprobación de tipo'''
def __init__(self, cols, rows, default_value=None,
initial_values=None, typed=True):
# Indicamos el número de columnas y filas de la matriz.
self.__cols = cols
self.__rows = rows
super(Matrix, self).__init__(cols * rows, default_value,
initial_values, typed)
def __setitem__(self, index, value):
# FIXME: interceptar índices no válidos.
col, row = index
index = self.__cols * row + col
super(Matrix, self).__setitem__(index, value)
def __getitem__(self, index):
# FIXME: interceptar índices no válidos.
col, row = index
index = self.__cols * row + col
return super(Matrix, self).__getitem__(index)
def __repr__(self):
result = ""
for i in range(0, self.length, self.cols):
result += "[%s]" % ", ".join([str(s) for s in self[i: i +
self.cols]])
return "[%s]" % result
def __str__(self):
result = ""
for i in range(0, self.length, self.cols):
result += "%s\n" % " ".join([str(s) for s in self[i: i +
self.cols]])
return result
@property
def cols(self):
return self.__cols
@property
def rows(self):
return self.__rows
def row(self, index):
'''Devuelve la fila con índice index'''
# FIXME: comprobar limites
i = index * self.__cols
return self[i:i + self.__cols]
def col(self, index):
'''Devuelve la columna con índice index'''
# FIXME: comprobar limites
return [self[index, i] for i in range(self.__cols)]
def submatrix(self, ix, iy, jx, jy):
'''Devuleve una submatrix de la matrix'''
m = []
for y in range(iy, jy + 1):
k = y * self.__cols
m.append(self[k + ix:k + jx + 1])
# OJO!! el valor devuelto es un lista y no de la clase matrix
return m
def list(self):
'''Devuleve los elementos de la matrix como una lista'''
return list(self)
def sublist(self, ix, iy, jx, jy):
'''Devuleve una submatrix de la matrix en forma de lista'''
l = []
for y in range(iy, jy + 1):
k = y * self.__cols
l.extend(self[k + ix:k + jx + 1])
# OJO!! el valor devuelto es un lista y no de la clase matrix
return l
def main():
a = Vector(10, 5,[])
a[3] = 4
print a
b = Vector(15, 2, [x for x in range(10)], False)
print b
print b.length
print b.type
b[1] = 'a'
print b
m = Matrix(3, 3, 0)
m[0, 0] = 1
m[1, 0] = 2
m[2, 0] = 3
m[0, 1] = 4
m[1, 1] = 5
m[2, 1] = 6
m[0, 2] = 7
m[1, 2] = 8
m[2, 2] = 9
print m
print repr(m)
x, y = 1, 1
print "item[%d, %d]: % d" % (x, y, m[x, y])
print "total items: %d" % len(m)
row = m.row(0)
print "row[0]: ", row
col = m.col(0)
print "col[0]: ", col
submatrix = m.submatrix(0,0,1,1)
print "submatrix[0,0][1,1]: ", submatrix
print 1 in submatrix
print 11 in submatrix
print m.list()
sublist = m.sublist(0,0,1,1)
print "sublist[0,0][1,1]: ", sublist
print 1 in sublist
print 11 in sublist
m2 = Matrix(4,4, 1, [1,2,3,4], False)
print m2
print m2.length
print m2.type
if __name__ == '__main__':
main()
_______________________________________________
Python-es mailing list
Python-es@python.org
http://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/