Brandon Brandon - 1 year ago 41
Python Question

Most pythonic way to extend a potentially incomplete list

What I'm looking for is the best way to say, 'If this list is too short, lengthen it to 9 elements and add 'Choice 4', 'Choice 5', etc, as the additional elements. Also, replace any 'None' elements with 'Choice x'.' It is ok to replace "" and 0 too.

An example transformation would be



['a','b','Choice 3','c','Choice 5','Choice 6','Choice 7','Choice 8','Choice 9']

My initial code abused try/except and had an off-by-one error I didn't notice; thanks to joeforker and everyone who pointed it out. Based on the comments I tried two short solutions that test equally well:

def extendChoices(cList):
for i in range(0,9):
if cList[i] is None:
cList[i] = "Choice %d"%(i+1)
except IndexError:
cList.append("Choice %d"%(i+1)


def extendChoices(cList):
# Fill in any blank entries
for i, v in enumerate(cList):
cList[i] = v or "Choice %s" % (i+1)

# Extend the list to 9 choices
for j in range(len(cList)+1, 10):
cList.append("Choice %s" % (j))

I think #2 wins as being more pythonic, so it's the one I'll use. It's easy to understand and uses common constructs. Splitting the steps is logical and would make it easier for someone to understand at a glance.


My initial reaction was to split the list extension and "filling in the blanks" into separate parts as so:

for i, v in enumerate(my_list):
    my_list[i] = v or "Choice %s" % (i+1)

for j in range(len(my_list)+1, 10):
    my_list.append("Choice %s" % (j))

# maybe this is nicer for the extension?
while len(my_list) < 10:
    my_list.append("Choice %s" % (len(my_list)+1))

If you do stick with the try...except approach, do catch a specific exception as Douglas shows. Otherwise, you'll catch everything: KeyboardInterrupts, RuntimeErrors, SyntaxErrors, ... . You do not want to do that.

EDIT: fixed 1-indexed list error - thanks DNS!

EDIT: added alternative list extension