0

m learning python from the google tutorials. am stuck on an exercise related to lists. getting an index error

  lis[j]=words.pop()[i]
IndexError: string index out of range

i need to sort the list but the words starting with x should be the first ones.

code is

def front_x(words):
    i=0
    lis=[]
    j=0
    k=0
    words.sort()

    while i<len(words):
        if words[i][0:1]=="x":
            lis[j]=words.pop()[i]
            j+=1
        i+=1
    lis.extend(words)
    while k<len(lis):
        print(lis[k])
        k+=1
    return
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343

2 Answers2

5

lis is an empty list, any index will raise an exception.

If you wanted to add elements to that list, use lis.append() instead.

Note that you can loop over sequences directly, there is no need to keep your own counter:

def front_x(words):
    lis = []
    words.sort()

    for word in words:
        if word.startswith("x"):
            lis.append(word)
    for entry in lis:
        print(entry)

You can reduce this further by immediately printing all words that start with x, no need to build a separate list:

def front_x(words):
    for word in sorted(words):
        if word.startswith("x"):
            print(word)

If you wanted to sort the list with all x words coming first, use a custom sort key:

def front_x(words):
    return sorted(words, key=lambda w: (not w.startswith('x'), w))

sorts the words first by the boolean flag for .startswith('x'); False is sorted before True so we negate that test, then the words themselves.

Demo:

>>> words = ['foo', 'bar', 'xbaz', 'eggs', 'xspam', 'xham']
>>> sorted(words, key=lambda w: (not w.startswith('x'), w))
['xbaz', 'xham', 'xspam', 'bar', 'eggs', 'foo']
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • ur method wud work if words starting with x are already in alphabetical order. but if not, this would fail. what exercise says is to arrange alphabetically the words with a condition that words starting with "x" shud be arranged first. – shanzyshan Jun 28 '13 at 13:22
  • @shanzyshan: No, it will not. The key returns a tuple; after sorting on the first value the items are sorted on the second. – Martijn Pieters Jun 28 '13 at 13:23
  • @martin. okk i'll try this. – shanzyshan Jun 28 '13 at 13:25
  • as u might have figured out i am new to python. one thing i am unable to understand is that how in the for *** in *** statements, the compiler is able to pick up things when we have not already defined them. for eg. in ur code this line is given for word in words we have just defined words as a list but how is compiler able to identify word. even in for word in sorted(words) neither is word defined and nor i think there is some command sorted(). can u explain me this? – shanzyshan Jun 28 '13 at 16:27
  • @shanzyshan: The grammar for Python states that `word` will be assigned *to*. The compiler knows it is a assignment target, so `word` will be defined as a local name just by using it in the loop statement. This is all documented in the [Python reference documentation](http://docs.python.org/2/reference/). – Martijn Pieters Jun 28 '13 at 16:31
0

i need to sort the list but the words starting with x should be the first ones.

Complementary to the custom search key in @Martijn's extended answer, you could also try this, which is closer to your original approach and might be easier to understand:

def front_x(words):
    has_x, hasnt = [], []
    for word in sorted(words):
        if word.startswith('x'):
            has_x.append(word)
        else:
            hasnt.append(word)
    return has_x + hasnt

Concerning what was wrong with your original code, there are actually three problems with the line

lis[j]=words.pop()[i]
  1. lis[j] only works if the list already has a jth element, but as you are adding items to an initially empty list, you should use lis.append(...) instead.
  2. You want to remove the word starting with "x" at index i from the list, but pop() will always remove the last item. pop() is for stacks; never remove items from a list while looping it with an index!
  3. You apply the [i] operator after you've popped the item from the list, i.e., you are accessing the ith letter of the word, which may be much shorter; thus the IndexError
tobias_k
  • 81,265
  • 12
  • 120
  • 179