I have a long and nested lists of parameters to throw out with a django template, but the visualization routine in the template processes them better if the parameters are ordered two by two. So I was trying to put together a simple function for reordering the original list accordingly. This is what I came up with:
def group_list_items_by_two(lista, listaexit\= []): lista_x \= [] if lista: lista_x.extend(lista) lista_x.reverse()
first\_el \= lista\_x.pop()
if len(lista\_x) \=\= 0:
second\_el \= None
else:
second\_el \= lista\_x.pop()
listaexit.append(\[first\_el, second\_el\])
if lista\[2:\]:
group\_list\_items\_by\_two(lista\[2:\], listaexit)
#print(listaexit)
return listaexit
Nothing too extraordinary till here -I'm quite sure I could have done this in a better way (been wondering if there is a way to iterate over a list two elements at a time..but hey.. still learning python!) - however the function had a weird behaviour:
>>> x \= [('aaaa', 6), ('bbbb', 7), ('cccc', 8)] >>> group_list_items_by_two(x) [[('aaaa', 6), ('bbbb', 7)], [('cccc', 8), None]] >>> group_list_items_by_two(x) [[('aaaa', 6), ('bbbb', 7)], [('cccc', 8), None], [('aaaa', 6), ('bbbb', 7)], ... [('cccc', 8), None]] >>> group_list_items_by_two(x) [[('aaaa', 6), ('bbbb', 7)], [('cccc', 8), None], [('aaaa', 6), ('bbbb', 7)], ....[('cccc', 8), None], [('aaaa', 6), ('bbbb', 7)], [('cccc', 8), None]] >>> x [('aaaa', 6), ('bbbb', 7), ('cccc', 8)]
Basically - python is not using the default argument I'm passing (listaexit= []) and instead it keeps adding to the same variable. WHY IS this totally counter-intuitive behaviour happening?
A little bit of googling gave me an answer...
The reason for this behaviour is that expressions in default arguments are calculated when the function is defined, not when it’s called (read this as well). The solution is to pass None as the default value, and then add a line 'listaexit = listaexit or []' to avoid None type floating around....
And here's a working version of the function above:
def group_list_items_by_two(lista, listaexit\= None): lista_x \= [] listaexit \= listaexit or [] if lista: lista_x.extend(lista) lista_x.reverse()
first\_el \= lista\_x.pop()
if len(lista\_x) \=\= 0:
second\_el \= None
else:
second\_el \= lista\_x.pop()
listaexit.append(\[first\_el, second\_el\])
if lista\[2:\]:
group\_list\_items\_by\_two(lista\[2:\], listaexit)
#print(listaexit)
return listaexit
Cite this blog post:
Comments via Github:
2019
2012
2011