35

Given a list:

words = ['aba', 'xyz', 'xgx', 'dssd', 'sdjh']

I need to compare the first and the last element of each string in the list. If the first and the last element in the string is the same, then increment the count.

If I try it manually, I can iterate over each element of the strings in the list:

words = ['aba', 'xyz', 'xgx', 'dssd', 'sdjh']
w1 = words[0]
print w1
aba

for i in w1:
   print i
 
a
b
a

if w1[0] == w1[len(w1) - 1]:
   c += 1
   print c
 
1

But, when I try to iterate over all the elements of all the strings in the list , using a for loop, I get an error.

words = ['aba', 'xyz', 'xgx', 'dssd', 'sdjh']
c = 0
for i in words:
     w1 = words[i]
     if w1[0] == w1[len(w1) - 1]:
       c += 1
     print c

ERROR:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: list indices must be integers, not str

How would I achieve comparing the first and the last element of a list of strings?

Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
user3168141
  • 371
  • 1
  • 3
  • 5
  • 3
    Iteration over a list returns its elements not indexes, hence the error. – Ashwini Chaudhary Jan 07 '14 at 10:09
  • 1
    Your Python one-liner to do what you want (but not solve or explain the bug) would look like: `c = sum([1 if w[0] == w[-1] else 0 for w in words])`. But that won't really help you until you start getting the hang of list-comprehensions (even shorter: `c = sum([int(w[0] == w[-1]) for w in words])`). –  Jan 07 '14 at 10:18
  • 1
    @Evert You can drop the `int` call and `[]` as well.. ;-) – Ashwini Chaudhary Jan 07 '14 at 10:19
  • @AshwiniChaudhary Hm, I don't like summing booleans like that, but I guess implicit conversion works here. I let it stand, otherwise your comment won't make sense ;-). –  Jan 07 '14 at 10:21
  • This question is awful; the title has nothing to do with the actual problem, and actively misleads people who arrive from a search engine. This is why it is important to attempt [debugging](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) and [research](https://meta.stackoverflow.com/questions/261592) before asking. People who actually have the question in the title are also better served by other duplicates. – Karl Knechtel Sep 25 '22 at 22:04

9 Answers9

54

Try:

for word in words:
    if word[0] == word[-1]:
        c += 1
    print c

for word in words returns the items of words, not the index. If you need the index sometime, try using enumerate:

for idx, word in enumerate(words):
    print idx, word

would output

0, 'aba'
1, 'xyz'
etc.

The -1 in word[-1] above is Python's way of saying "the last element". word[-2] would give you the second last element, and so on.

You can also use a generator to achieve this.

c = sum(1 for word in words if word[0] == word[-1])
Steinar Lima
  • 7,644
  • 2
  • 39
  • 40
3

The suggestion that using range(len()) is the equivalent of using enumerate() is incorrect. They return the same results, but they are not the same.

Using enumerate() actually gives you key/value pairs. Using range(len()) does not.

Let's check range(len()) first (working from the example from the original poster):

words = ['aba', 'xyz', 'xgx', 'dssd', 'sdjh']
    print range(len(words))

This gives us a simple list:

[0, 1, 2, 3, 4]

... and the elements in this list serve as the "indexes" in our results.

So let's do the same thing with our enumerate() version:

words = ['aba', 'xyz', 'xgx', 'dssd', 'sdjh']    
   print enumerate(words)

This certainly doesn't give us a list:

<enumerate object at 0x7f6be7f32c30>

...so let's turn it into a list, and see what happens:

print list(enumerate(words))

It gives us:

[(0, 'aba'), (1, 'xyz'), (2, 'xgx'), (3, 'dssd'), (4, 'sdjh')]

These are actual key/value pairs.

So this ...

words = ['aba', 'xyz', 'xgx', 'dssd', 'sdjh']

for i in range(len(words)):
    print "words[{}] = ".format(i), words[i]

... actually takes the first list (Words), and creates a second, simple list of the range indicated by the length of the first list.

So we have two simple lists, and we are merely printing one element from each list in order to get our so-called "key/value" pairs.

But they aren't really key/value pairs; they are merely two single elements printed at the same time, from different lists.

Whereas the enumerate () code:

for i, word in enumerate(words):
    print "words[{}] = {}".format(i, word)

... also creates a second list. But that list actually is a list of key/value pairs, and we are asking for each key and value from a single source -- rather than from two lists (like we did above).

So we print the same results, but the sources are completely different -- and handled completely differently.

fra
  • 205
  • 1
  • 3
  • 7
2

The reason is that in your second example i is the word itself, not the index of the word. So

for w1 in words:
     if w1[0] == w1[len(w1) - 1]:
       c += 1
     print c

would the equivalent of your code.

ShinTakezou
  • 9,432
  • 1
  • 29
  • 39
1

The following code outputs the number of words whose first and last letters are equal. Tested and verified using a python online compiler:

words = ['aba', 'xyz', 'xgx', 'dssd', 'sdjh']  
count = 0  
for i in words:  
     if i[0]==i[-1]:
        count = count + 1  
print(count)  

Output:

$python main.py
3
Rann Lifshitz
  • 4,040
  • 4
  • 22
  • 42
ibsa
  • 11
  • 2
0

Use range() instead, like the following :

for i in range(len(words)):
    ...
Johanna
  • 1,343
  • 4
  • 25
  • 44
0
c=0
words = ['challa','reddy','challa']

for idx, word in enumerate(words):
    if idx==0:
        firstword=word
        print(firstword)
    elif idx == len(words)-1:
        lastword=word
        print(lastword)
        if firstword==lastword:
            c=c+1
            print(c)
Serenity
  • 35,289
  • 20
  • 120
  • 115
0

You are iterating trough items in words but you have to iterate through item's length:

words = ['aba', 'xyz', 'xgx', 'dssd', 'sdjh']
c = 0
for i in range(len(words)):
    w1 = words[i]
    if w1[0] == w1[len(w1) - 1]:
      c += 1
    print (c)

In your case i[0] is 'aba' because i is calculated from items in words:

words = ['aba', 'xyz', 'xgx', 'dssd', 'sdjh']
c = 0
for i in words:
print(i)

the output is:

aba

Denya56
  • 60
  • 1
  • 9
0

You can solve this problem using sum() and a generator expression. When intepreted as integers, booleans that are True have a value of 1, and booleans that are False have a value of 0. So, we can do the following:

sum(word[0] == word[-1] for word in words)
BrokenBenchmark
  • 18,126
  • 7
  • 21
  • 33
-1
for i,j in enumerate(words): # i---index of word----j
     #now you got index of your words (present in i)
     print(i) 
jizhihaoSAMA
  • 12,336
  • 9
  • 27
  • 49