Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Most pythonic way to extend a potentially incomplete list

Tags:

python

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',None,'c']

to

['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):
    try:
      if cList[i] is None:
        cList[i] = "Choice %d"%(i+1)
    except IndexError:
      cList.append("Choice %d"%(i+1)

and

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.

like image 707
gravitation Avatar asked Feb 05 '09 14:02

gravitation


People also ask

How do you extend a list in a string in Python?

The extend() method in Python adds the iterable elements (list, tuple, string etc.) to the end of the list. The length of the list is increased by the number of elements present in the iterable.

How do you extend a line in Python?

The preferred way of wrapping long lines is by using Python's implied line continuation inside parentheses, brackets and braces. If necessary, you can add an extra pair of parentheses around an expression, but sometimes using a backslash looks better. Make sure to indent the continued line appropriately.


1 Answers

Unlike zip, Python's map automatically extends shorter sequences with None.

map(lambda a, b: b if a is None else a,
    choicesTxt,
    ['Choice %i' % n for n in range(1, 10)])

You could simplify the lambda to

map(lambda a, b: a or b,
    choicesTxt,
    ['Choice %i' % n for n in range(1, 10)])

if it's okay to treat other false-like objects in choicesTxt the same as None.

like image 84
ephemient Avatar answered Oct 04 '22 13:10

ephemient