Okey so basically I have to check if one string has the same letters of another string. Both strings are obtained via input().
I don't want to double check if a letter is in the other string, so if I already checked that letter I want to skip to the next letter.
The code I have for now is this:
str1, str2 = list(input()), list(input())
if len(str1) > len(str2):
str = str1
else:
str = str2
for x in str:
c = 0
if x in str2:
c += 1
if c != 0:
print("Both have the same letters!")
else:
print("Nope there are some letters missing..")
I don't know if I should work with the lists instead of using a counter.. please a detailled explanation of the solution or some good quality guidance would be very appreciated! <3
Converting strings to sets of individual symbols remove duplicate symbols, so we can simply compare them:
if set(str1) == set(str2):
print("Both have the same letters!")
else:
print("Nope there are some letters missing..")
Note:
As the order of elements in sets is not important, we may even compare them, e. g.
if set(str1) <= set(str2): # <= means "is subset" in this context
print("All symbols in str1 are in str2, too.")
or
if set(str1) < set(str2): # < means "is a proper subset" in this context
print("All symbols in str1 are in str2, too, "
"but str2 has at least 1 symbol not contained in str1.")
Some issues with the code are that, str2 is always used for comparison even if str2 is longer than str1
for x in str:
c = 0
if x in str2:
Next, c is set to 0 for every character in str, Instead you can have a counter to count the number of chars not in the other string
This should do the job
str1, str2 = list(input()), list(input())
if len(str1) > len(str2):
str = str1
compared_string = str2
else:
str = str2
compared_string = str1
not_in_other_string = 0
for x in str:
if x not in compared_string:
not_in_other_string += 1
if not_in_other_string == 0:
print("Both have the same letters!")
else:
print("Nope there are some letters missing..")
It sounds like you want to find if all of the characters in one string are in some larger string.
You could use unique = ''.join(set(substring)) to get a list of chars in the substring and then make a list comprehension to get all the chars in the larger string.
Here is my example:
unique = ''.join(set(substring))
not_in = [char for char in unique if char not in superstring]
Now you can check not_in to see if it is null, otherwise there was a char in the substring that was not in the superstring.
For example:
superstring = "hello"
substring = "xllo"
unique = ''.join(set(substring))
not_in = [char for char in unique if char not in superstring]
print not_in
>>>['x']
print not_in == []
>>>False
Typically, the preferred way to do things in python is using list comprehensions or use some built in function that already checks strings for you, rather than the C style where you go through a loop and check letter for letter explicitly. This is the idiomatic way of pythonic programming.
Breaking apart the list comprehension we have a loop like this:
for char in unique:
if char not in superstring:
char #char meets conditions so it is the value used in [char ...
Here would be the modification I would make
str1, str2 = input(), input()
unique = ''.join(set(str1))
not_in = [char for char in unique if char not in str2]
if not_in == []:
print("Both have the same letters!")
else:
print("Nope there are some letters missing..")
str1, str2 = input().split()
if len(str1) > len(str2):
string_to_check= str1
string_from_which_to_check = str2
else:
string_to_check = str2
string_from_which_to_check = str1
not_in_other_string = set(string_to_check) - set(string_from_which_to_check)
if len(not_in_other_string )==0:
print("character are present in string")
else:
print("{} not present in string".format(str(not_in_other_string )))
Related
I have a string str1 = "This is Kane and Kane is a coder" and another string str2 = "tsk"
Now i want to remove all the characters of str2 which are appearing in str1 and store in another variable say word1
The result im expecting is
str1 = "hi i ane and ane i a coder"
word1 = TssKKs
word1 = ''
for i in str2:
if i in str1.lower():
word1 += i
str1 = str1.lower().replace(i,'')
I guess this is not very optimised method as im running a loop for each character of str2 which will affect the time for long strings
In your example code, for every letter in str2, it needs to iterate over str1 2 times: in the line if i in str1.lower() and in str1.replace(i,''). This means 6 times in in the example.
The following solution only iterates over str1 once and the check against a set is fast. It builds 2 new strings in parallel in one pass.
str1 = "This is Kane and Kane is a coder"
str2 = "tsk"
word = ""
new_str = ""
remove = set(str2)
for letter in str1:
if letter.lower() in remove:
word += letter
else:
new_str += letter
print(word)
print(new_str)
I mean in order to get the correct order and capitalization of word1 you probably need to loop over str1, so:
new_str1 = ""
word1 = ""
for c in str1:
if c in set(str2):
word1 += c
else:
new_str1 +=c
And if capitalization don't matter.
well word1 = set(str2) and
import re
str1 = re.sub("[tsK]","", str1)
For short string like str2 the algorithm would not affect the performance and an optimisation would be exaggerating. Still, as it is short you can get rid of the inner loop and use an if statement instead. And you don't need to call lower in each loop. Just call it before entering the for:
word1 = ''
str1 = str1.lower()
for i in str1:
if i == "t" or i == "s" or i == "k":
word1 += i
str1 = str1.replace(i,'')
This should be way faster as the other letters are not tested against once one condition has evaluated to true.
And as #jarmod said, no need to convert a str to list, as str is iterable.
EDIT: for a case sensitive letters in word1, you need to use a temp variable:
word1 = ''
str1_low = str1.lower()
count = 0
for i in str1_low:
count = count + 1
if i == "t" or i == "s" or i == "k":
word1 += str1[count]
str1 = str1[:count] + str1[count+1:]
#variable defination#
lower="abcdefghijklmnopqrstuvwxyz"
upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
valid=True
x=0
g=0
string=input("enter a string:")
#data validation#
for char in string:
if char in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ":
valid=True
else:
valid=False
#finding the character#
if valid:
for char in string:
g+=1
for ele in upper:
if char!=ele:
x+=1
print(lower[x]+string[g::])
**I can't get it to work, it keeps iterating through the entire string without the condition ever being met. **
Since you are allowed to use lowercase and uppercase character inputs, you can create a dictionary mapping between them and use str.join with a list comprehension:
from string import ascii_lowercase, ascii_uppercase
d = dict(zip(ascii_uppercase, ascii_lowercase))
string = input("enter a string:")
res = ''.join([d.get(i, i) for i in string])
It's not clear whether this satisfies your "no in-built function" requirement.
I tried to minimize changes from your original code (But remember, it's obvious that other solutions are much better.)
#variable defination#
lower="abcdefghijklmnopqrstuvwxyz"
upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
string=input("enter a string:")
#data validation#
valid = True
for char in string:
if char not in lower + upper:
valid=False
#finding the character#
if valid:
result = ""
for char in string:
if char in lower:
result += char
else:
# uppercase character
for i in range(len(upper)):
if char == upper[i]:
result += lower[i]
break
print(result)
You can create mapping(dictionary) between uppercase and lowercase alphabets such that upper_to_lower[uppercase] should give you lowercase. You may refer below implementation as reference though.
import string
def to_lower_case(word):
# construct auxilliary dictionary to avoid ord and chr built-in methods
upper_to_lower = {}
for index in range(len(string.ascii_uppercase)): # this is 26 we can use it as constant though
upper_to_lower[string.ascii_uppercase[index]] = string.ascii_lowercase[index]
result = ''
for alphabet in word:
if alphabet in string.ascii_uppercase:
result += upper_to_lower[alphabet]
else:
result += alphabet
return result
# sample input
In [5]: to_lower_case('ANJSNJN48982984aadkaka')
Out[5]: 'anjsnjn48982984aadkaka'
You can also write an index method to get the index of an uppercase character in the upper string:
lower = "abcdefghijklmnopqrstuvwxyz"
upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def index(char):
i = 0
for c in upper:
if char == c: return i
i += 1
Then you can convert your string to lowercase like this:
#data validation#
# ...
#finding the character#
s = ''
if valid:
for char in string:
if char in lower: s += char
else: s += lower[index(char)]
print(s)
If I have a string
String = 'ABCEEFGH'
How can I check what letter is beside each letter without going out of index?
for index in range(len(String)):
if String[index] == String[index+1]:
print('Double')
You can use enumerate, slicing the string up to the second last character:
String = 'ABCEEFGH'
for ind,ch in enumerate(String[:-1]):
if ch == String[ind+1]:
print('Double')
In your own code the logic would be the same len(String)-1 but enumerate is the way to go:
for index in range(len(String)-1):
if String[index] == String[index+1]:
print('Double')
The fact you seen to only want to check if any two adjacent characters are identical, maybe using any would be best:
String = 'ABCEEFGH'
if any( ch == String[ind+1] for ind, ch in enumerate(String[:-1])):
print('Double',ch)
any will short circuit and break the loop as soon the condition is Trueor else evaluate to False if we have no match.
>>> text = 'ABCEEFGH'
>>> for c1, c2 in zip(text, text[1:]):
if c1 == c2:
print 'double'
double
These kinds of problems are almost always easier if you think of comparing with the previous letter instead of the next one. It's a lot easier to remember letters you've already seen than to look ahead.
text = 'ABCEEFGH'
prev = ''
for letter in text:
if letter == prev:
print("letter duplicated:", letter)
prev = letter
You can use regular expressions:
for match in re.findall(r'([a-z])\1', your_string):
print('Double letters found here.')
So I was doing our exercise when I came across capitalizing characters in odd indices. I tried this:
for i in word:
if i % 2 != 0:
word[i] = word[i].capitalize()
else:
word[i] = word[i]
However, it ends up showing an error saying that not all strings can be converted. Can you help me debug this code snippet?
The problem is strings in python are immutable and you cannot change individual characters. Apart fro that when you iterate through a string you iterate over the characters and not the indices. So you need to use a different approach
A work around is
(using enumerate)
for i,v in enumerate(word):
if i % 2 != 0:
word2+= v.upper()
# Can be word2+=v.capitalize() in your case
# only as your text is only one character long.
else:
word2+= v
Using lists
wordlist = list(word)
for i,v in enumerate(wordlist):
if i % 2 != 0:
wordlist[i]= v.upper()
# Can be wordlist[i]=v.capitalize() in your case
# only as your text is only one character long.
word2 = "".join(wordlist)
A short note on capitalize and upper.
From the docs capitalize
Return a copy of the string with its first character capitalized and the rest lowercased.
So you need to use upper instead.
Return a copy of the string with all the cased characters converted to uppercase.
But in your case both work accurately. Or as Padraic puts it across "there is pretty much no difference in this example efficiency or output wise"
You need enumerate and capitalise any character at any odd i where i is the index of each char in the word:
word = "foobar"
print("".join( ch.upper() if i % 2 else ch for i, ch in enumerate(word)))
fOoBaR
ch.upper() if i % 2 else ch is a conditional expression where we change the char if the condition is True or else leave as is.
You cannot i % 2 when i is the actual character from the string, you would need to use range in your code or use enumerate and concatenate the changed characters to an output string or make words a list.
Using a list you can use assignment:
word = "foobar"
word = list(word)
for i, ele in enumerate(word):
if i % 2:
word[i] = ele.upper()
print("".join(word))
Using an output string:
word = "foobar"
out = ""
for i, ele in enumerate(word):
if i % 2:
out += ele.upper()
else:
out += ele
if i % 2: is the same as writing if i % 2 != 0.
This is how I would change word letters in a word or a sentence to uppercase
word = "tester"
letter_count = 1
new_word = []
for ch in word:
if not letter_count % 2 == 0:
new_word.append(ch.upper())
else:
new_word.append(ch)
letter_count += 1
print "".join(new_word)
if I wanted to change odd words in a sentence to uppercase I would do this
sentence = "this is a how we change odd words to uppercase"
sentence_count = 1
new_sentence = []
for word in sentence.split():
if not sentence_count % 2 == 0:
new_sentence.append(word.title() + " ")
else:
new_sentence.append(word + " ")
sentence_count += 1
print "".join(new_sentence)
I think it will help...
s = input("enter a string : ")
for i in range(0,len(s)):
if(i%2!=0):
s = s.replace(s[i],s[i].upper())
print(s)
I was wondering how to reverse two characters in a string.
Here are some examples:
'wing' => 'iwng', 'inwg', 'ingw'
'west' => 'ewst', 'eswt', 'estw'
I was going to use any answers given and put it in a while loop so I can get all the possible combinations of a string while swapping two characters at a time.
ex.
counter = 0
while (counter <= len(str1)):
if str1 == reverse(str2):
return str2
elif str1 == str2
return str2
else:
str1 = *some code that would swap the the characters m and n*
str1 =
n += 1
m += 1
return False
This code compares two strings, str1 to str2, and checks to see if they are the same by swapping the characters around.
ALSO, is there a way i can get this to produce a list of the results instead of printing them?
THANKS!
Try this:
s = 'wing'
s = 'west'
l = [x for x in s]
for i in xrange(len(s)-1):
l[i], l[i+1] = l[i+1], l[i]
print "".join(l)
In order to generate all possibilities, we can use:
s = "yourstring"
for i in range(0,len(s)-2):
if i>0: print s[:i]+s[i+1:i-1:-1]+s[i+2:]
else: print s[1]+s[0]+s[2:]
Since you wish to actually compare two strings to see if they "are the same by swapping two characters around," you do not actually need to generate all possible combinations, instead you can iterate through each of the characters in each of the strings and ensure that no more than two of them are not equal.
This can be done as follows:
def twoCharactersDifferent(str1,str2):
if sorted(str1) != sorted(str2): #they must contain the same letters, exactly!
return False
numDifferent = 0
for i in range(len(str1)):
numDifferent += (str1[i] != str2[i])
if numDifferent >2:
return False
return True
print twoCharactersDifferent('wings','winxg')