Taking into account that it partidos
is a list with sublists that contain tuples. Ex:partidos = [[(datetime.date(2000, 9, 9), 'FC Barcelona', 2, 'Málaga CF', 1)], [(datetime.date(2000, 9, 9), 'RC Deportivo', 2, 'Athletic Club', 0)], [(datetime.date(2000, 9, 9), 'Real Sociedad', 2, 'R. Racing C.', 2)]]
I have tried to build the following function to do what you ask:
def partidos_por_fecha(partidos, inicio=None, fin=None):
''' Filtra los partidos jugados en un rango de fechas
ENTRADA:
- partidos: lista de partidos -> [Partido(datetime.date, str, int, str, int)]
- inicio: fecha inicial del rango -> datetime.date
- fin: fecha final del rango -> datetime.date
SALIDA:
- lista de partidos seleccionados -> [Partido(datetime.date, str, int, str, int)]
Se devuelven aquellos partidos que se han jugado entre las fechas inicio
y fin. Ambos parámetros serán objetos date del módulo datetime.
Si inicio es None, se incluirán los partidos desde el principio de
la serie, y si fin es None se inlcuirán los partidos hasta el último de
la serie.
'''
if inicio == None:
inicio = partidos[0][0][0]
elif fin == None:
fin = partidos[-1][-1][0]
elif inicio == None and fin == None:
inicio = partidos[0][0][0]
fin = partidos[-1][-1][0]
else:
inicio == inicio
fin == fin
result = []
for i in partidos:
for fecha, local, goles_local, visitante, goles_visitante in i:
if fecha >= inicio and fecha <= fin:
result.append((fecha, local, goles_local, visitante, goles_visitante))
return result
This function is executed by the following code:
def test_partidos_por_fechas(partidos):
inicio = datetime(2007, 9, 15).date()
fin = datetime(2008, 7, 1).date()
print(len(partidos_por_fecha(partidos, inicio, fin)))
print(len(partidos_por_fecha(partidos, inicio, None)))
print(len(partidos_por_fecha(partidos, None, fin)))
print(len(partidos_por_fecha(partidos, None, None)))
test_partidos_por_fechas(partidos)
The error that I get after executing the function is:
TypeError: '<=' not supported between instances of 'datetime.date' and 'NoneType'
And it tells me that it is in the if
one that is inside the loops for
. I don't understand how after filtering the arguments inicio
and fin
when they are None
before the loops for
, I still get variables None
to compare withdatetimes
I would like to get some solution to make the function work. Sorry if there are indentation errors in the code having passed it here and thanks in advance.
There are some bugs in the code:
Comparison with
None
is recommended to be done using the operatoris
, ieif inicio is None
, etc. instead ofif inicio == None
. The reason for this is quite technical (if you're interested I can explain it in a final note).In this particular case, this detail does not affect the operation of the code, but get used to doing it with it
is
as a general rule.In it
else:
you have a==
where I think you wanted to do an assignment (=
). This doesn't matter either because it never enters throughelse
, as we'll see right away, but it was obviously wrong.The most important bug is the logic of the ones
if
with which you want to assign values toinicio
andfin
in case they don't have one. Note that if both areNone
, the firstif inicio == None:
will be fulfilled, and its body will be executed without executing any of the other cases , so in that casefin
it will remain with itsNone
initial value, and this case is the one that "breaks" you.The simplest solution would be the following:
That is, I use a second
if
instead of aelif
. If itinicio
isNone
, it is assigned a default value. Then, independently, the same thing is done withfin
. If both wereNone
, both will be assigned. The weird assignmentinicio=inicio; fin=fin
you had inelse:
it is obviously not necessary, as it leaves the variables as they were.Another possibility
In some python code you may come across the following "trick". I personally have mixed feelings about it. On the one hand, the number of lines of code is reduced. On the other hand, it makes use of a "weird" feature that can be considered poorly readable. Although if you get used to seeing it, it ends up being quite readable...
It is like this:
It can almost be read effortlessly as "assign to
inicio
what was ininicio
, or else this other value (if what was ininicio
wasNone
)" .The reason it works is because the result of a
or
Python expression is the value of the last term evaluated that makes the expression true, or the last term if neither is true.Thus, if for example
inicio
it is worth 20, itinicio or otra_cosa
is true (since 20 is considered asTrue
when it is part of a Boolean expression, and therefore the expression is true just by evaluating the first term, so the second is not even evaluated) , and the result would be20
. However if itinicio
isNone
(either zero, or the empty string, or some other value that is consideredFalse
by python) then python must evaluateotra_cosa
to determine the result of theor
. The final result of the expression will be the value ofotra_cosa
.It is a rare hack , and I don't know whether to recommend its use or advise against it, but you should know about it because you will see it written many times.
Finally, python also has something equivalent to the C ternary operator,
v = condicion?valor_cierto:valor_falso
, which in python would bev = valor_cierto if condicion else valor_falso
.Using this in your case:
if
This is basically just another way of putting the one I put in the first part of the answer in fewer lines . I almost prefer the "in more lines" version as it is clearer.