 # FAQ: Introduction to Strings - Strings and Conditionals (Part Two)

This community-built FAQ covers the “Strings and Conditionals (Part Two)” exercise from the lesson “Introduction to Strings”.

Paths and Courses
This exercise can be found in the following Codecademy content:

## Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply ( ) below!

Agree with a comment or answer? Like ( ) to up-vote the contribution!

Found a bug? Report it!

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

3 posts were split to a new topic: I can just use return?

19 posts were split to a new topic: How to not get duplicate letters?

2 posts were split to a new topic: Used a brute force method; is it a bit messy?

hello,
need to know the mistake in this code
def contains(big_string, little_string):
for character in big_string:
if character == little_string:
return True
and when i look at the solution i don’t understand the answer of the first Q

This will return on the first True, meaning iteration will not be complete. Be sure to completely compare little_string.

Think in terms of slices. We can measure the length of little_string and then iterate over big_string and compare equal length slices when the first letter of little_string is encountered.

What’s more, the above is comparing a character to a string, not a character.

While this is not the recommended solution, since it is not an algorithm (the preferred solution at this level)…

`````` return little_string in big_string
``````

The above uses membership testing with the `in` operator. Our algorithm will want to emulate this, but in a loop construct.

``````def contains(haystack, needle):
n = len(needle)
f = needle
for i, x in enumerate(haystack):
if x == f:
if haystack[i:n + i] == needle:
return True
return False

print (contains('superimposed', 'impose'))    # True
``````

Now if we assume that the `enumerate` function is as yet unknown to you, then we can revert to `range` to obtain the index, and the current character.

``````for i in range(len(big_string)):
if big_string[i] == f:
if big_string[i:n + i] == little_string:
``````

Of course, the above solutions both assume that you are familiar with slicing. If not, then we need to get more creative using only the concepts currently in your tool belt.

We’re now eight hours later, and have this to consider that uses none of the above, only the `range`, as suggested.

``````# without slicing or enumerate
def has_in(haystack, needle):
k = range(len(needle))
h = range(len(haystack))
f = needle
r = False
for i in h:
if haystack[i] == f:
for j in k:
if haystack[i + j] == needle[j]:
r = True
continue
else:
r = False
break
if r: return r
return r

print (has_in('superimposed self-imposed', 'impose'))      # True
print (has_in('superimposed self-imposed', 'imposter'))    # False
``````

https://repl.it/@mtf/needle-haystack-found-string-in-string

Above we could technically return the index, as well, but it would be to the first match, not subsequent matches. That will take more logic.

Such as,

``````def has_at(haystack, needle):
k = range(len(needle))
h = range(len(haystack) - k[-1])
f = needle
r = False
s = []
for i in h:
if haystack[i] == f:
for j in k:
if haystack[i + j] == needle[j]:
r = True
continue
else:
r = False
break
if r: s.append(i)
return s or r

print (has_at('superimposed self-imposed impose', 'impose'))      # [5, 18, 26]
print (has_at('superimposed self-imposed impose', 'imposter'))    # False
``````

Why in my code i get {“a”, “n”} instead of [“a”, “n”]

`def common_letters`(string_one, string_two):
letters =
`for` L `in` string_one:
`if` L `in` string_two:
letters += L
letters.sort()
`return` set(letters)

The return value is a set; ergo, the delimiters, `{` and `}`.

Hello!

I know that I’ve tried to solve it differently by going at it differently and not using “in” for both parameters and I’ve understood how to answer the question.

However, I’m having trouble understanding why the code I’ve written always seems to be returning an empty list.

``````def common_letters(string_one, string_two):
common_lst = []
for char1 in string_one:
for char2 in string_two:
if char1 == char2 and char1 not in common_lst == True:
common_lst.append(char1)
return common_lst
``````

**Edit:

I’ve also tried changing the indentation of the `return common_lst` with no avail. So far I understand the concepts taught in this course pretty well, but for some reason I always struggle with indentation!

Unnecessary to write `== True`.

Is it really necessary to iterate both strings? Consider that `in` is a sort of iterator as it seeks membership. Iterating over one string (either one) and searching `in` the other will certainly detect any matches.

Hi mtf,

Could you please clarify what you mean regarding `in`?

in returns True or False all by itself. You don’t need to add `== True`.

``````my_str = 'abcde'
print('abc' in my_str)
print('xyz' in my_str)
``````

Output:

``````True
False
``````

Incidentally, due to operator precedence, and the way chaining works, your expression won’t work as you expect:

``````print('xyz' not in my_str ==  True)
``````

Output:

``````False
``````

The chained expression is evaluated as follows:

``````('xyz' not in my_str) and (my_str ==  True)
``````

… which returns False, since the second term returns False.

2 Likes

Woah. Took me a good minute to see that there was comparison chaining there even after you said it. That’s pretty surprising. I’d never write that, but I’d also never spot it by only reading it.

1 Like

Owing that `in` (membership) and `==` (identity) have equal precedence, operations occur from left to right

``````'xyz' not in my_str  => True
True == True         => True``````

…no
but that’s how I would first read it, too.

1 Like
``````>>> my_str = 'abcdef'
>>> 'xyz' not in my_str
True
>>> 'xyz' not in my_str == True
False
>>>
``````

I stand corrected, thank you.

1 Like

This time explicitly made sure I used loops haha

``````def contains(big_string, little_string):
maybe = False
if big_string.count(little_string):
maybe = True
return maybe

def common_letters(string_one, string_two):
new = []
if len(string_one) >= len(string_two):
for i in string_one:
if i not in new and i in string_two:
new.append(i)
else:
for i in string_two:
if i not in new and i in string_one:
new.append(i)
return new
``````

Silliness

``````>>> def common_letters(a, b):
r = {}
c, d = (a, b) if len(a) < b else (b, a)
for x in c:
if x in d:
r[x] = 1
return list(r.keys())

>>> common_letters('impossible', 'impasse')
['i', 'p', 's', 'm', 'e']
>>>
``````

Even sillier…

``````>>> def common_letters(a, b):
if len(a) > b: a, b = b, a
return list({x: 1 for x in a if x in b}.keys())

>>> common_letters('impossible', 'impasse')
['i', 'p', 's', 'm', 'e']
>>>
``````

The latter comes up in advanced topics later in the course (if they haven’t been covered yet)… dictionary comprehensions.

1 Like

Couple of observations.

• In a previous exercise you returned a bool with a single line. Why not here in `contains()`?

• In `common_letters` what difference does it make which list is longer?

We really only need to iterate the shorter list and check for membership in the longer one.

1 Like