Used a brute force method; is it a bit messy?

#1

The interpreter is order sensitive, so [a, b] != [b, a], if anyone has a better/clever solution please share. Used a brute force method so its a bit messy:


def contains(big_string, little_string):
  return little_string in big_string

def common_letters(string_one, string_two):
  
  pairs = []
  str1 = len(string_one)
  min = str1
  str2 = len(string_two)
  max = str2
  
  if str1 > str2:
    max = str1
    min = str2
    for letter in range(0, min, 1):
      if contains(string_one, string_two[letter]):
        pairs.append(string_two[letter])
  else:
    for letter in range(0, min, 1):
      if contains(string_two, string_one[letter]):
        pairs.append(string_one[letter])
  
  for i in range(0, len(pairs), 1):
    for j in range(i + 1, len(pairs), 1):
      if pairs[j] == pairs[i]:
        return pairs[:j]
  return list(set(pairs))
   
print(contains("banana", "cream"))
print(common_letters('manhattan', 'san francisco'))
print(common_letters('python', 'ruby on rails'))
1 Like
FAQ: Introduction to Strings - Strings and Conditionals (Part Two)
FAQ: Introduction to Strings - Strings and Conditionals (Part Two)
#2

What is the output of the three print statements?

This may not be clever, and if sets have not come up yet it will be out of place. However, since your return value is a set, we may as well explore it…

>>> a = set('abdigmqry')
>>> b = set('bimfhoy')
>>> a
{'q', 'i', 'a', 'b', 'd', 'm', 'g', 'y', 'r'}
>>> b
{'i', 'b', 'm', 'o', 'h', 'y', 'f'}
>>> a.intersection(b)
{'m', 'i', 'b', 'y'}
>>> 
>>> a, b = 'manhattan', 'san francisco'
>>> set(a).intersection(set(b))
{'n', 'a'}
>>> a, b = 'python', 'ruby on rails'
>>> set(a).intersection(set(b))
{'n', 'y', 'o'}
>>> 

The only real problem with all this simplicity is we lose the orginal order, though that is hardly a real problem. But, if we wish to preserve the order, then sets are out (as are dictionaries).

We discussed earlier how we only need to iterate over one string, a character at a time, and compare it to the other string. If it has not yet been cached in the return list, then append it. Once the string has been completely iterated, return the resulting list.

spoiler
  common = []
  for x in string_one:
    if x in string_two:
      if x not in common:
        common.append(x)
  return common

Since the lesson is specifically focusing on the in operator, we should make use of it in our solution so we have an example to come back to in future.

2 Likes
#3

If you care about letter counts, collections.Counter also supports intersection


found a bug by reading it

common_letters('aab', 'aab')

Because this looked incredibly shady:

There’s no reason why you would have seen all all in-common letters at that point, so a counter example is easily constructed with a letter re-appearing before all others have been seen.

I got suspicious seeing that the code had a special case to a problem that doesn’t really have special cases. Find and de-duplicate, right? That doesn’t fork off into two paths, just do one and then the other.

2 Likes
#4

def common_letters1(string_one, string_two):
common_list =
for character_one in string_one:
for character_two in string_two:
if character_one == character_two:
common_list.append(character_one)
common_letter = set(common_list)
return common_letter

#5

This is my suggestion for how to solve the task. Since sets are not yet introduced in the scope of this exercise I used the in keyword again to check if the matched character was already in my list of common_letters before appending it.

def common_letters(string_one, string_two):
  common_letters = []
  for letter in string_one:
    if letter in string_two:
      if letter not in common_letters:
        common_letters.append(letter)
  return common_letters
2 Likes
#6
def common_letters(string_one, string_two):
  common = []
  for i in range(len(string_one)):
    if string_one[i] in string_two and not string_one[i] in common:
      common.append(string_one[i])
    else:
      continue
  return common
#7

Is there a question to go with this? Please don’t post to post.

#8
def common_letters(string_one,string_two):
  foo = []
  for letter in string_one:
    if letter in string_two and letter not in foo: foo += letter
  return foo

I’m sure there are even more compact ways to do this if you know more of the methods available in python

1 Like
#9

It’s a direct answer to the question in the original post

if anyone has a better/clever solution please share.

#10

Nothing of the sort. It only comes so long after the OP as to have a need for some sort of explanation accompanying it. Just dropping in a piece code on a moribund thread is something of a distubance. Who is being answered?

#11

Don’t know if this helps, but this was my method.

def common_letters(string_one, string_two):
same_letters =
for letter in string_one:
if letter in string_two and same_letters.count(letter) == 0:
same_letters.append(letter)
return same_letters