user3636636
user3636636

Reputation: 2499

Iterate through two strings, returning the count when characters at the same index match

I have two words, one is a user input string, the other is a randomly selected word from text file. I would like to return the count values that are equal in both stings and share the same string index. e.g word1 = 'bleed', word2 = slice: similar = 1.

word1 = 'frog'
word2 = 'friend'
correct = 0

if len(word1) > len(word2):
    for i in range(len(word2)):
        if word1[i] == word2[i]:
            correct =+ 1
        else:
            correct == 0

else:
   for i in range(len(word1)):
       if word1[i] == word2[i]:
           correct =+ 1
       else:
           correct == 0

I'm new to programming and unfortunately My attempt maxes out at correct = 1. For the words i have used in the example frog and friend i would expect to see correct = 2, my code produces correct = 1. How do i add to correct, beyond 1? thank you

Upvotes: 5

Views: 16555

Answers (5)

fliedonion
fliedonion

Reputation: 952

example for 'reduce' .

>>> word1 = 'frog'
>>> word2 = 'friend'
>>> reduce(lambda z,(x,y): (z+1) if x == y else z, zip(word1,word2), 0)
2

reduce take 3 arguments,

  • function called with accumulator and each item of the list.
  • list.
  • initial value of accumulator.

Accumulator looks like temporary variable. But the value of the accumulator is taken over.

In my code:

function is The value of the accumulator is taken over.
list is zip(word1, word2) so [('f', 'f'), ('r', 'r'), ('o', 'i'), ('g', 'e')]
initial value is 0

Let's see how reduce works.

First time, function called with arguments z := 0, (x,y) := ('f', 'f') and return 1, because x == y is True and z + 1 is 1.

Next time, function called with arguments z := 1, (x,y) := ('r', 'r'). z is 1, that is point, please remember accumulator is taken over. so z is last result. In this time, x == y is True, too. function return 2 (z + 1).

Next time, called with 2, ('o', 'i') returns 2. ( 'o' is not 'i' ).

And last, called with 2, ('g', 'e') returns 2.

That's all, result was 2.

Upvotes: 2

scorpiodawg
scorpiodawg

Reputation: 5752

This is much easier with zip() and the filter() built in function:

Python 2.x:

In [23]: word1 = 'frog'
In [24]: word2 = 'friend'
In [25]: print len(filter(lambda (x, y): x == y, zip(word1, word2)))
2

Python 3.x (see comments for pointers re: changes):

>>> word1 = 'frog'
>>> word2 = 'friend'
>>> len(list(filter(lambda xy: xy[0] == xy[1], zip(word1, word2))))
2

Update: since you're new to programming, I'll attempt to explain this solution a bit:

Python has support for sequences (commonly thought of as an ordered list of items), such as [1,2,3] or ['a', 'b', 'c', 123, 456]. However, Python treats strings as an ordered list of characters as well, so 'hello world' is also a list. As a result, you may apply Python's list-related operators/built-in functions on strings as well. Therefore your problem reduces to treat word1 and word2 as lists and find indexes on these lists where their items match.

So let's use Python's special functions for this.zip is a nifty function that takes more than one sequence, and makes a new list with each item at index X made up of the values at index X in each of the input sequences. For instance, zip([1,2], [3,4]) becomes [(1,3), (2,4)] and zip('foo', 'bar') becomes [('f', 'b'), ('o', 'a'), ('o', 'r')]. This last result is very useful for your problem -- now you just need to run a function through each tuple (i.e. a value of the form (x,y)) through a function to check if the values are equal. You could do that in a loop as in other languages, but you can also make Python do the looping for you and provide just a function that returns the result of applying equality to each tuple on a list by using a function such as filter() or map(). In your case, you want filter() which runs through the input list and includes every value in the original list that causes the value of a passed in function (the lambda in the solution) to be True. The length of the "filtered" list is essentially the number of matches.

Hope this helps. Note that if you are new to Python, you will want to look up list/sequences, tuples, zip, filter, and lambda in a good book or the official Python reference to fully understand the solution.

Oh, and welcome to programming :-)

Upvotes: 9

Jack Leow
Jack Leow

Reputation: 22477

Using zip and for comprehension:

word1 = 'frog'
word2 = 'friend'

sum([1 for (l,r) in zip(word1, word2) if l == r])

Upvotes: 3

MrAlias
MrAlias

Reputation: 1346

To start with, =+ needs to be += to properly increment correct, and get rid of your else clauses as they do nothing.

As mentioned in the comments you should look into zip

In [1]: word1 = 'frog'

In [2]: word2 = 'friend'

In [3]: sum(1 for a, b in zip(word1, word2) if a == b)
Out[3]: 2

Upvotes: 1

Ruben Bermudez
Ruben Bermudez

Reputation: 2323

As user2347112 stated in comments, this task can be easily done with zip() built-in funciton:

word1 = 'frog'
word2 = 'friend'
correct = 0

for i,j in zip(word1,word2):
    if i == j:
        correct+=1

print(correct)

Upvotes: 1

Related Questions