Python looping through string and matching it with with wildcard pattern - python

string1="abc"
string2="abdabcdfg"
I want to find if string1 is substring of string2. However, there are wildcard characters like "." can be any letter, y can be "a" or "d", x can be "b" or "c".
as a result, ".yx" will be substring of string2.
How can I code it using only one loop? I want to loop through string2 and make comparisons at each index. i tried dictionary but I wand to use loop
my code:
def wildcard(string,substring):
sum=""
table={'A': '.', 'C': '.', 'G': '.', 'T': '.','A': 'x', 'T': 'x', 'C': 'y', 'G': 'y'}
for c in strand:
if (c in table) and table[c] not in sum:
sum+=table[c]
elif c not in table:
sum+=c
if sum==substring:
return True
else:
return False
print wildcard("TTAGTTA","xyT.")#should be true

I know you are specifically asking for a solution using a loop. However, I would suppose a different approach: You can easily translate your pattern to a regular expression. This is a similar language for string patterns, just much more powerful. You can then use the re module to check whether that regular expression (and thus your substring pattern) can be found in the string.
def to_regex(pattern, table):
# join substitutions from table, using c itself as default
return ''.join(table.get(c, c) for c in pattern)
import re
symbols = {'.': '[a-z]', '#': '[ad]', '+': '[bc]'}
print re.findall(to_regex('.+#', symbols), 'abdabcdfg')
If you prefer a more "hands-on" solution, you can use this, using loops.
def find_matches(pattern, table, string):
for i in range(len(string) - len(pattern) + 1):
# for each possible starting position, check the pattern
for j, c in enumerate(pattern):
if string[i+j] not in table.get(c, c):
break # character does not match
else:
# loop completed without triggering the break
yield string[i : i + len(pattern)]
symbols = {'.': 'abcdefghijklmnopqrstuvwxyz', '#': 'ad', '+': 'bc'}
print list(find_matches('.+#', symbols, 'abdabcdfg'))
Output in both cases is ['abd', 'bcd'], i.e. it can be found two times, using these substitutions.

Related

Using regular expression, list all the letters that follows a vowel according to their occurrence frequency

How can I find consonants letters that came after the vowels in words of string and count the frequency
str = 'car regular double bad '
result19 = re.findall(r'\b\w*[aeiou][^ aeiou]\w*\b' , str)
print(result19) #doesn't work
Expected output
letter r count = 2
letter b count = 1
letter d count = 1
I am not sure whether this is what you want or not, but it might help as an answer and not a comment.
I think you are on the right track, but you need a few modifications and other lines to achieve the excepted:
import re
myStr = 'car regular double bad '
result19 = re.findall(r'[aeiou][^aeiou\s]+' , myStr)
myDict = {}
for value in result19:
if not value[1] in myDict:
myDict[value[1]] = 0
myDict[value[1]] += 1
myDict
This will result in a dictionary containing the values and the number the have appeared:
{'b': 1, 'd': 1, 'g': 1, 'l': 1, 'r': 2}
For having a better output you can use a for loop to print each key and its value:
for chr, value in myDict.items():
print(chr, "->", value)
Output
r -> 2
g -> 1
l -> 1
b -> 1
d -> 1
Your pattern \b\w*[aeiou][^ aeiou]\w*\b matches zero or more repetitions of a word character using \w* and only matches a single occurrence of [aeiou][^ aeiou] in the "word"
If you want to match all consonant letters based on the alphabet a-z after a vowel, you can match a single occurrence of [aeiou] and use a capture group matching a single consonant.
Then make use of re.findall to return a list of the group values.
import re
txt = 'car regular double bad '
lst = re.findall(r'[aeiou]([b-df-hj-np-tv-z])', txt)
dct = {c: lst.count(c) for c in lst}
print(dct)
Output
{'r': 2, 'g': 1, 'l': 1, 'b': 1, 'd': 1}
If you want to match a non whitespace char other than a vowel after matching a vowel, you can use this pattern [aeiou]([^\saeiou])
Note that the l is also in the output as it comes after the u in ul

How to replace given index in String with Dictionary value in python?

The instructions are to replace certain characters within a string to the corresponding value in the dictionary.
Here is my code:
word = input()
password = ''
wordDict = {
'i': '!',
'a': '#',
'm': 'M',
'B': '8',
'o': '.',
}
for i in range(len(word)):
if word[i] in wordDict.keys():
word.replace(word[i], wordDict.get(word[i]))
i += 1
else:
i += 1
print(word)
The problem with my code is that nothing about the given password is changing nor does it seem to be iterating through the for loop.
Your problem is with this line:
word.replace(word[i], wordDict.get(word[i]))
Strings in Python, as well as many other languages, are immutable, meaning you can't edit the string.
The function you're calling (str.replace) doesn't replace the character in the string, it returns a new str with the character replaced.
The easiest, though naive if you want this to work efficiently, solution is to replace it with this line:
word = word.replace(word[i], wordDict.get(word[i]))

Getting a word from numbers with combinations

i'll make an example: i have the word lol that can be 1o1. the number "1" can be used as l, i, j. i have a blacklisted word list blacklisted = ['lol']. I want to change the "1" numbers in 1o1 to verify if it is egual to lol. Example: result = ['ioi', 'joj', 'lol', 'joi']...
is there a way to do that?
blacklisted = ['lol']
check = ['1o1']
substitute = ['l', 'i', 'j']
result = [ check[0].replace('1', char) for char in substitute ]
print(result)
Obiously, you can generalize the snippet above for other values than '1' and use it in a loop that checks many words.
Use a dictionary to store these similar values. For example, here's a function to implement this functionality:
def check(string, blacklisted):
translate_dict = {'1': ['l', 'i', 'j']} # etc. for similar corresponding values
possible_strings = []
for num, letter in translate_dict.items(): # this loop replaces all numbers with letters
for i in letter:
possible_strings.append(string.replace(num, i))
for string in possible_strings:
if string in blacklisted: # checks whether the string is in blacklisted
return False
return True

python - check if word is in list full of strings and if there is print the words in an another list

so basically it would be like:
MyList=["Monkey","Phone","Metro","Boom","Feet"]
and let's say I have the input be m so Boom and Monkey and Metro would be put in a list like so
output >> ["Monkey","Metro","Feet"]
and if I would've had the input be f then the output would be
output >> ["Feet"]
and my question is how would I put this in a def? This is what I came up with
def Find(word,MyList):
MyList2=[]
count=0
for i in MyList:
count+=1
if i[count] == MyList2: ##(at first i did if i[0:10])
for x in range(1):
MyList2.append(i)
print(MyList2)
and then somewhere there should be
word=input("Word, please.")
and then
Find(word,MyList)
thanks in advance!
Try this :
def find_words(input_char, my_list):
ret_list = []
for i in my_list:
if input_char.lower() in i.lower():
ret_list.append(i)
return ret_list
MyList=["Monkey","Phone","Metro","Boom","Feet"]
input_char=input("Input a character :").strip() # get a character and strip spaces if any.
find_words(input_char, MyList) # call the function with arguments
Output for sample input "M :
Input a character :>? "M"
>>> ['Monkey', 'Metro', 'Boom']
(Almost) One liner:
>>> MyList=["Monkey","Phone","Metro","Boom","Feet"]
>>> target = input("Input string: ")
Input string: Ph
>>> print([i for i in MyList if target.lower() in i.lower()])
['Phone']
Generally in Python you don't want to be playing with indexes, iterators are the way to go.
The in keyword checks for substrings so it will work whether you provide only one character or a full string too (i.e. if you input Ph you'll get a list containing only Phone)
Depending on how efficient you want your search would be. Throwing in one more approach to build a dictionary like this
from collections import defaultdict
d = defaultdict(set)
for i in MyList:
chars = set(i)
for c in chars:
d[c].add(i)
Now, your dictionary looks like this
defaultdict(set,
{'o': {'Boom', 'Metro', 'Monkey', 'Phone'},
'k': {'Monkey'},
'e': {'Feet', 'Metro', 'Monkey', 'Phone'},
'M': {'Metro', 'Monkey'},
'y': {'Monkey'},
'n': {'Monkey', 'Phone'},
'h': {'Phone'},
'P': {'Phone'},
't': {'Feet', 'Metro'},
'r': {'Metro'},
'm': {'Boom'},
'B': {'Boom'},
'F': {'Feet'}})
Now, you can simply search within your dict with O(1) complexity
d[your_input_char]
Here is how you can use a list comprehension:
def Find(letter, MyList):
print([word for word in MyList if letter.lower() in word.lower()])
Find('m', ["Monkey","Phone","Metro","Boom","Feet"])
Output:
['Monkey', 'Metro', 'Boom']

Python: Creating a new list that is dependent on the content of another list

I am passing a function a list populated with strings. I want this function to take each of those strings and iterate through them, executing two different actions depending on the letters found in each string, then displaying them as the separate and now changed strings in a new list.
Specifically, when the program iterates through each string and finds a consonant, it should write that consonant in the order that it was found, into the new list. If the program finds a vowel in the current string, it should append 'xy' before the vowel, then the vowel itself.
As an example:
If the user input: "how now brown cow", the output of the function should be: "hxyow nxyow brxyown cxyow". I've tried nested for loops, nested while loops, and variations between. What's the best way to accomplish this? Cheers!
For every character in old string check if it is vowel or consonant and create new string accordingly.
old = "how now brown cow"
new = ""
for character in old:
if character in ('a', 'e', 'i', 'o', 'u'):
new = new + "xy" + character
else:
new = new + character
print(new)
I gave you the idea and now I leave it as exercise to make it work for list of strings. Also make appropriate changes if you are using python2.
>>> def xy(st):
... my_list,st1 =[],''
... for x in st:
... if x in 'aeiou':
... st1 += 'xy'+x
... elif x in 'cbdgfhkjmlnqpsrtwvyxz':
... my_list.append(x)
... st1 += x
... return my_list,st1
...
>>> my_string="how now brown cow"
>>> xy(my_string)
(['h', 'w', 'n', 'w', 'b', 'r', 'w', 'n', 'c', 'w'], 'hxyow nxyow brxyown cxyow')
In above function for iterates through string when it find vowel concatenate xy+vowel else it append consonant to list, at last returns list and string
A simple way to do this using a list comprehension:
old_str = "how now brown cow"
new_str = ''.join(["xy" + c if c in "aeiou" else c for c in old_str])
print new_str
But if you're processing a lot of data it'd be more efficient to use a set of vowels, eg
vowels = set("aeiou")
old_str = "how now brown cow"
new_str = ''.join(["xy" + c if c in vowels else c for c in old_str])
print new_str
Note that these programs simply copy all characters that aren't vowels, i.e., spaces, numbers and punctuation get treated as if they were consonants.

Categories