How to not get duplicate letters?

Hi all, I read the posts to this thread, and I now understand how to program the solution to second part of this exercise. Thank you!

However, I still do not understand why the code that I wrote does not work. My solution is not very concise nor elegant, but I would really appreciate it if someone could explain to me why I get an infinite loop when I run it. Here is my code:

def remove_repeats(lst):
  index1 = len(lst) - 1
  while index1 >= 0:
    index2 = 0
    while index2 < len(lst) - 1:
      if index2 != index1 and lst[index2] == lst[index1]:
        lst.remove(lst[index2])
        index2 += 1
        print("Index2 is: " + str(index2))

    index1 -= 1
    print("Index1 is: " + str(index1))

  print(lst)
  return lst

def common_letters(string_one, string_two):
  common = []

  for char in string_two:
    if char in string_one:
      common.append(char)
    
  print(common)
  new_common = remove_repeats(common)

  return new_common

common_letters('manhattan', 'san francisco')

The way my code (ideally) was supposed to work was the function remove_repeats could take in the initial list of shared letters and remove the letters that are repeated within the list.

In the function remove_repeats, I used a nested loop. In the outer loop, index1 was supposed to be the index of the character I was comparing to the rest of the characters in the list, and index2 was the index of the other characters in the list.

However, I just realized that if I remove an element within the inner while loop, would that change the number of indexes (is this why my code will not work)? I am still not sure why I get an infinite loop.

This is not a standard way of doing it, but it does work while leveraging how greedy str.replace() is.

>>> def remove_repeats(s):
	b = ''
	for a in s[:]:
		s = s.replace(a, '')
		b += a
		if s == '': break
	return b

>>> remove_repeats('abababab')
'ab'
>>> 

I used the following to get through this exercise.

def common_letters(string_one, string_two):
____common =
____for n in string_one:
_______if n in string_two:
_________if n in common:
___________continue
_________else:
___________common.append(n)
_______return common

The way I understood it is that using the ‘in’ function taught in the prior lesson, python would iterate through the list and check the letters ‘in’ string one against the letters ‘in’ string two and if they were already ‘in’ the common list, then ‘continue’ would skip that letter and move on to the next - else, it would append the common list.

side note: It wouldn’t work at first because it took me a second to realize that my ‘return’ statement was indented wrong.

I tried to use the list comprehension method but I couldn’t get it to stop duplicating letters in the list. I’m not sure why? Has anyone been successful using this method?

There is no way to examine the contents of the list we are building since we cannot refer to any of its elements until the list is completed.

I don’t think that comprehension is the way to go here. But you have a good solution. Although, you can combine your if conditions and make code a bit smaller using not. For example this is my solution:

def common_letters(string_one, string_two):
  common = []
  for i in string_one:
    if (i in string_two) and not (i in common):
      common += i
  return common

One of the major gripes among Python coders is the abundant use of brackets in other languages. We need very few of them in Python.

>>> def common_letters(string_one, string_two):
  common = []
  for i in string_one:
    if i in string_two and i not in common:
      common += i
  return common

>>> common_letters('string_one', 'string_two')
['s', 't', 'r', 'i', 'n', 'g', '_', 'o']
>>> 
1 Like

Good point. Thank you!

1 Like

If you think about it, you have already written the “contains method” so utilize that to find if the letter has already been added to the list.

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

def common_letters(string_one, string_two):

  lst = []
  for letter in string_one:
    if letter in string_two and contains(lst, letter) == False:
      lst.append(letter)
  return lst

I’m late to this conversation…
but no, it was not covered. Because of this, I was totally confused as well (and ended up here).

Reading through the explanations, the use of not makes total sense, I just wish I had been shown it before the exercise.

We feel your pain. Needless, we get on with it or fail. Choose now.

1 Like

My first Solution:

def common_letters(string_one, string_two):
common =
for char1 in string_one:
for char2 in string_two:
if char1 == char2:
if char1 not in common:
common.append(char1)
print(common)
return common

My second solution:

def common_letters(string_one, string_two):
common =
for letter in string_one:
if letter in string_two and letter not in common:
common.append(letter)
print(common)
return common

I find solution 2 to be much more readable. Until this challenge I didn’t realize you could use multiple key words in a row, such as “not in”