Making sure only a particular group of characters are in a string - python

Is there any way to make sure that only the characters 'm' 'c' 'b' are in a string without resorting to regex?
For instance, if the user inputs 'm', the program will print 'Major'. If the user inputs 'mc', the program will print 'Major, Critical'.
So I want to make sure that if the user inputs something like 'mca', the program will print 'Not applicable'.
try:
if 'a' in args.findbugs:
if len(args.findbugs) > 1:
print 'findbugs: Not an applicable argument.'
else:
print 'FINDBUGS:ALL'
else:
if 'm' in args.findbugs:
print 'FINDBUGS:MAJOR'
if 'c' in args.findbugs:
print 'FINDBUGS:CRITICAL'
if 'b' in args.findbugs:
print 'FINDBUGS:BLOCKER'
except TypeError:
print "FINDBUGS: NONE"

Well, the simplest way from what you've described would be:
some_string = 'mca'
if set(some_string) <= {'m', 'c', 'b'}:
# The string contains only 'm', 'c', or 'b'.
else:
# The string 'mca' does not match because of 'a'.
Or, if you intend to require at least m, c, or b:
some_string = 'mca'
if set(some_string) & {'m', 'c', 'b'}:
# The string contains 'm', 'c', or 'b', so 'mca' will match.
NOTE: As pointed out by bgporter, the set literal notation is not available in Python versions less than 2.7. If support for those is required, use set(('m', 'c', 'b')).

This is a way to check it in linear time.
s = "blabla"
l = 'mcb'
print all(x in l for x in s)

Crude, but this would return what you need.
input not in itertools.combinations('mcb', 1) + itertools.combinations('mcb', 2) + itertools.combinations('mcb', 3)

arg_dict = {"m":'FINDBUGS:MAJOR',"c": 'FINDBUGS:CRITICAL',"b": 'FINDBUGS:BLOCKER'}
accepted =["m","c","b"]
user_args = "bccm"
if all(x in accepted for x in user_args):
for x in set(user_args):
print (arg_dict.get(x),
else:
print ("FINDBUGS: NONE")
FINDBUGS:CRITICAL FINDBUGS:BLOCKER FINDBUGS:MAJOR
If you want them in order sort the input:
accepted =["m","c","b"]
user_args = "bcm"
if all(x in accepted for x in user_args):
user_args = sorted(set(user_args),key=lambda x: accepted.index(x))
for x in user_args:
print "{} ".format((format(arg_dict.get(x)))),
else:
print ("FINDBUGS: NONE")
FINDBUGS:MAJOR FINDBUGS:CRITICAL FINDBUGS:BLOCKER

Related

python string match partial match [duplicate]

How can I check if any of the strings in an array exists in another string?
For example:
a = ['a', 'b', 'c']
s = "a123"
if a in s:
print("some of the strings found in s")
else:
print("no strings found in s")
How can I replace the if a in s: line to get the appropriate result?
You can use any:
a_string = "A string is more than its parts!"
matches = ["more", "wholesome", "milk"]
if any([x in a_string for x in matches]):
Similarly to check if all the strings from the list are found, use all instead of any.
any() is by far the best approach if all you want is True or False, but if you want to know specifically which string/strings match, you can use a couple things.
If you want the first match (with False as a default):
match = next((x for x in a if x in str), False)
If you want to get all matches (including duplicates):
matches = [x for x in a if x in str]
If you want to get all non-duplicate matches (disregarding order):
matches = {x for x in a if x in str}
If you want to get all non-duplicate matches in the right order:
matches = []
for x in a:
if x in str and x not in matches:
matches.append(x)
You should be careful if the strings in a or str gets longer. The straightforward solutions take O(S*(A^2)), where S is the length of str and A is the sum of the lenghts of all strings in a. For a faster solution, look at Aho-Corasick algorithm for string matching, which runs in linear time O(S+A).
Just to add some diversity with regex:
import re
if any(re.findall(r'a|b|c', str, re.IGNORECASE)):
print 'possible matches thanks to regex'
else:
print 'no matches'
or if your list is too long - any(re.findall(r'|'.join(a), str, re.IGNORECASE))
A surprisingly fast approach is to use set:
a = ['a', 'b', 'c']
str = "a123"
if set(a) & set(str):
print("some of the strings found in str")
else:
print("no strings found in str")
This works if a does not contain any multiple-character values (in which case use any as listed above). If so, it's simpler to specify a as a string: a = 'abc'.
You need to iterate on the elements of a.
a = ['a', 'b', 'c']
str = "a123"
found_a_string = False
for item in a:
if item in str:
found_a_string = True
if found_a_string:
print "found a match"
else:
print "no match found"
a = ['a', 'b', 'c']
str = "a123"
a_match = [True for match in a if match in str]
if True in a_match:
print "some of the strings found in str"
else:
print "no strings found in str"
jbernadas already mentioned the Aho-Corasick-Algorithm in order to reduce complexity.
Here is one way to use it in Python:
Download aho_corasick.py from here
Put it in the same directory as your main Python file and name it aho_corasick.py
Try the alrorithm with the following code:
from aho_corasick import aho_corasick #(string, keywords)
print(aho_corasick(string, ["keyword1", "keyword2"]))
Note that the search is case-sensitive
The regex module recommended in python docs, supports this
words = {'he', 'or', 'low'}
p = regex.compile(r"\L<name>", name=words)
m = p.findall('helloworld')
print(m)
output:
['he', 'low', 'or']
Some details on implementation: link
A compact way to find multiple strings in another list of strings is to use set.intersection. This executes much faster than list comprehension in large sets or lists.
>>> astring = ['abc','def','ghi','jkl','mno']
>>> bstring = ['def', 'jkl']
>>> a_set = set(astring) # convert list to set
>>> b_set = set(bstring)
>>> matches = a_set.intersection(b_set)
>>> matches
{'def', 'jkl'}
>>> list(matches) # if you want a list instead of a set
['def', 'jkl']
>>>
Just some more info on how to get all list elements availlable in String
a = ['a', 'b', 'c']
str = "a123"
list(filter(lambda x: x in str, a))
It depends on the context
suppose if you want to check single literal like(any single word a,e,w,..etc) in is enough
original_word ="hackerearcth"
for 'h' in original_word:
print("YES")
if you want to check any of the character among the original_word:
make use of
if any(your_required in yourinput for your_required in original_word ):
if you want all the input you want in that original_word,make use of all
simple
original_word = ['h', 'a', 'c', 'k', 'e', 'r', 'e', 'a', 'r', 't', 'h']
yourinput = str(input()).lower()
if all(requested_word in yourinput for requested_word in original_word):
print("yes")
flog = open('test.txt', 'r')
flogLines = flog.readlines()
strlist = ['SUCCESS', 'Done','SUCCESSFUL']
res = False
for line in flogLines:
for fstr in strlist:
if line.find(fstr) != -1:
print('found')
res = True
if res:
print('res true')
else:
print('res false')
I would use this kind of function for speed:
def check_string(string, substring_list):
for substring in substring_list:
if substring in string:
return True
return False
Yet another solution with set. using set.intersection. For a one-liner.
subset = {"some" ,"words"}
text = "some words to be searched here"
if len(subset & set(text.split())) == len(subset):
print("All values present in text")
if subset & set(text.split()):
print("Atleast one values present in text")
If you want exact matches of words then consider word tokenizing the target string. I use the recommended word_tokenize from nltk:
from nltk.tokenize import word_tokenize
Here is the tokenized string from the accepted answer:
a_string = "A string is more than its parts!"
tokens = word_tokenize(a_string)
tokens
Out[46]: ['A', 'string', 'is', 'more', 'than', 'its', 'parts', '!']
The accepted answer gets modified as follows:
matches_1 = ["more", "wholesome", "milk"]
[x in tokens for x in matches_1]
Out[42]: [True, False, False]
As in the accepted answer, the word "more" is still matched. If "mo" becomes a match string, however, the accepted answer still finds a match. That is a behavior I did not want.
matches_2 = ["mo", "wholesome", "milk"]
[x in a_string for x in matches_1]
Out[43]: [True, False, False]
Using word tokenization, "mo" is no longer matched:
[x in tokens for x in matches_2]
Out[44]: [False, False, False]
That is the additional behavior that I wanted. This answer also responds to the duplicate question here.
data = "firstName and favoriteFood"
mandatory_fields = ['firstName', 'lastName', 'age']
# for each
for field in mandatory_fields:
if field not in data:
print("Error, missing req field {0}".format(field));
# still fine, multiple if statements
if ('firstName' not in data or
'lastName' not in data or
'age' not in data):
print("Error, missing a req field");
# not very readable, list comprehension
missing_fields = [x for x in mandatory_fields if x not in data]
if (len(missing_fields)>0):
print("Error, missing fields {0}".format(", ".join(missing_fields)));

Converting mobile numeric keypad numbers to its corresponding word Python

I need to create a function, where, If I give an input like 999933. It should give output as "ze". It basically work as numeric mobile phone keypad. How can I this. I have searched to get some sample in internet. All, I got was quite opposite. Like, Giving the text as input and you will get the number. I couldn't get the exact flow of, how to achieve that. Please let me know, how can i do that.
def number_to_text(val):
pass
Create a mapping pad_number to letter.
Use itertools.groupby to iterate over consecutive pad presses and calculate which letter we get.
import itertools
letters_by_pad_number = {"3": "def", "9": "wxyz"}
def number_to_text(val):
message = ""
# change val to string, so we can iterate over digits
digits = str(val)
# group consecutive numbers: itertools.groupby("2244") -> ('2', '22'), ('4','44')
for digit, group in itertools.groupby(digits):
# get the pad letters, i.e. "def" for "3" pad
letters = letters_by_pad_number[digit]
# get how many consecutive times it was pressed
presses_number = len(list(group))
# calculate the index of the letter cycling through if we pressed
# more that 3 times
letter_index = (presses_number - 1) % len(letters)
message += letters[letter_index]
return message
print(number_to_text(999933))
# ze
And hardcore one-liner just for fun:
letters = {"3": "def", "9": "wxyz"}
def number_to_text(val):
return "".join([letters[d][(len(list(g)) - 1) % len(letters[d])] for d, g in itertools.groupby(str(val))])
print(number_to_text(999933))
# ze
The other answers are correct, but I tried to write a less brief more real world (including doctests) explanation of how the previous results worked:
dialpad_text.py:
# Import the groupby function from itertools,
# this takes any sequence and returns an array of groups by some key
from itertools import groupby
# Use a dictionary as a lookup table
dailpad = {
'2': ['a', 'b', 'c'],
'3': ['d', 'e', 'f'],
'4': ['g', 'h', 'i'],
'5': ['j', 'k', 'l'],
'6': ['m', 'n', 'o'],
'7': ['p', 'q', 'r', 's'],
'8': ['t', 'u', 'v'],
'9': ['w', 'x', 'y', 'z'],
}
def dialpad_text(numbers):
"""
Takes in either a number or a string of numbers and creates
a string of characters just like a nokia without T9 support
Default usage:
>>> dialpad_text(2555222)
'alc'
Handle string inputs:
>>> dialpad_text('2555222')
'alc'
Handle wrapped groups:
>>> dialpad_text(2222555222)
'alc'
Throw an error if an invalid input is given
>>> dialpad_text('1BROKEN')
Traceback (most recent call last):
...
ValueError: Unrecognized input "1"
"""
# Convert to string if given a number
if type(numbers) == int:
numbers = str(numbers)
# Create our string output for the dialed numbers
output = ''
# Group each set of numbers in the order
# they appear and iterate over the groups.
# (eg. 222556 will result in [(2, [2, 2, 2]), (5, [5, 5]), (6, [6])])
# We can use the second element of each tuple to find
# our index into the dictionary at the given number!
for number, letters in groupby(numbers):
# Convert the groupby group generator into a list and
# get the offset into our array at the specified key
offset = len(list(letters)) - 1
# Check if the number is a valid dialpad key (eg. 1 for example isn't)
if number in dailpad.keys():
# Add the character to our output string and wrap
# if the number is greater than the length of the character list
output += dailpad[number][offset % len(dailpad[number])]
else:
raise ValueError(f'Unrecognized input "{number}"')
return output
Hope this helps you understand what's going on a lower level! Also if you don't trust my code, just save that to a file and run python -m doctest dialpad_text.py and it will pass the doctests from the module.
(Notes: without the -v flag it won't output anything, silence is golden!)
You need to
group the same digits together with the regex (\d)\1* that capture a digit then the same digit X times
use the value of a digit in the group to get the key
use the length of it to get the letter
phone_letters = ["", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"]
def number_to_text(val):
groups = [match.group() for match in re.finditer(r'(\d)\1*', val)]
result = ""
for group in groups:
keynumber = int(group[0])
count = len(group)
result += phone_letters[keynumber][count - 1]
return result
print(number_to_text("999933")) # ze
Using list comprehension
def number_to_text(val):
groups = [match.group() for match in re.finditer(r'(\d)\1*', val)]
return "".join(phone_letters[int(group[0])][len(group) - 1] for group in groups)
A slightly Modified answer of RaFalS without using itertools
import itertools
from collections import defaultdict
letters_by_pad_number = {"3": "def", "9": "wxyz"}
val = 999933
message = ""
digits = str(val)
num_group = defaultdict(int)
for digit in digits:
num_group[digit] += 1
for num in num_group.keys():
message += letters_by_pad_number[num][num_group[num]-1]
print(message)
# ze

How to check for multi strings in a line [duplicate]

How can I check if any of the strings in an array exists in another string?
For example:
a = ['a', 'b', 'c']
s = "a123"
if a in s:
print("some of the strings found in s")
else:
print("no strings found in s")
How can I replace the if a in s: line to get the appropriate result?
You can use any:
a_string = "A string is more than its parts!"
matches = ["more", "wholesome", "milk"]
if any([x in a_string for x in matches]):
Similarly to check if all the strings from the list are found, use all instead of any.
any() is by far the best approach if all you want is True or False, but if you want to know specifically which string/strings match, you can use a couple things.
If you want the first match (with False as a default):
match = next((x for x in a if x in str), False)
If you want to get all matches (including duplicates):
matches = [x for x in a if x in str]
If you want to get all non-duplicate matches (disregarding order):
matches = {x for x in a if x in str}
If you want to get all non-duplicate matches in the right order:
matches = []
for x in a:
if x in str and x not in matches:
matches.append(x)
You should be careful if the strings in a or str gets longer. The straightforward solutions take O(S*(A^2)), where S is the length of str and A is the sum of the lenghts of all strings in a. For a faster solution, look at Aho-Corasick algorithm for string matching, which runs in linear time O(S+A).
Just to add some diversity with regex:
import re
if any(re.findall(r'a|b|c', str, re.IGNORECASE)):
print 'possible matches thanks to regex'
else:
print 'no matches'
or if your list is too long - any(re.findall(r'|'.join(a), str, re.IGNORECASE))
A surprisingly fast approach is to use set:
a = ['a', 'b', 'c']
str = "a123"
if set(a) & set(str):
print("some of the strings found in str")
else:
print("no strings found in str")
This works if a does not contain any multiple-character values (in which case use any as listed above). If so, it's simpler to specify a as a string: a = 'abc'.
You need to iterate on the elements of a.
a = ['a', 'b', 'c']
str = "a123"
found_a_string = False
for item in a:
if item in str:
found_a_string = True
if found_a_string:
print "found a match"
else:
print "no match found"
a = ['a', 'b', 'c']
str = "a123"
a_match = [True for match in a if match in str]
if True in a_match:
print "some of the strings found in str"
else:
print "no strings found in str"
jbernadas already mentioned the Aho-Corasick-Algorithm in order to reduce complexity.
Here is one way to use it in Python:
Download aho_corasick.py from here
Put it in the same directory as your main Python file and name it aho_corasick.py
Try the alrorithm with the following code:
from aho_corasick import aho_corasick #(string, keywords)
print(aho_corasick(string, ["keyword1", "keyword2"]))
Note that the search is case-sensitive
The regex module recommended in python docs, supports this
words = {'he', 'or', 'low'}
p = regex.compile(r"\L<name>", name=words)
m = p.findall('helloworld')
print(m)
output:
['he', 'low', 'or']
Some details on implementation: link
A compact way to find multiple strings in another list of strings is to use set.intersection. This executes much faster than list comprehension in large sets or lists.
>>> astring = ['abc','def','ghi','jkl','mno']
>>> bstring = ['def', 'jkl']
>>> a_set = set(astring) # convert list to set
>>> b_set = set(bstring)
>>> matches = a_set.intersection(b_set)
>>> matches
{'def', 'jkl'}
>>> list(matches) # if you want a list instead of a set
['def', 'jkl']
>>>
Just some more info on how to get all list elements availlable in String
a = ['a', 'b', 'c']
str = "a123"
list(filter(lambda x: x in str, a))
It depends on the context
suppose if you want to check single literal like(any single word a,e,w,..etc) in is enough
original_word ="hackerearcth"
for 'h' in original_word:
print("YES")
if you want to check any of the character among the original_word:
make use of
if any(your_required in yourinput for your_required in original_word ):
if you want all the input you want in that original_word,make use of all
simple
original_word = ['h', 'a', 'c', 'k', 'e', 'r', 'e', 'a', 'r', 't', 'h']
yourinput = str(input()).lower()
if all(requested_word in yourinput for requested_word in original_word):
print("yes")
flog = open('test.txt', 'r')
flogLines = flog.readlines()
strlist = ['SUCCESS', 'Done','SUCCESSFUL']
res = False
for line in flogLines:
for fstr in strlist:
if line.find(fstr) != -1:
print('found')
res = True
if res:
print('res true')
else:
print('res false')
I would use this kind of function for speed:
def check_string(string, substring_list):
for substring in substring_list:
if substring in string:
return True
return False
Yet another solution with set. using set.intersection. For a one-liner.
subset = {"some" ,"words"}
text = "some words to be searched here"
if len(subset & set(text.split())) == len(subset):
print("All values present in text")
if subset & set(text.split()):
print("Atleast one values present in text")
If you want exact matches of words then consider word tokenizing the target string. I use the recommended word_tokenize from nltk:
from nltk.tokenize import word_tokenize
Here is the tokenized string from the accepted answer:
a_string = "A string is more than its parts!"
tokens = word_tokenize(a_string)
tokens
Out[46]: ['A', 'string', 'is', 'more', 'than', 'its', 'parts', '!']
The accepted answer gets modified as follows:
matches_1 = ["more", "wholesome", "milk"]
[x in tokens for x in matches_1]
Out[42]: [True, False, False]
As in the accepted answer, the word "more" is still matched. If "mo" becomes a match string, however, the accepted answer still finds a match. That is a behavior I did not want.
matches_2 = ["mo", "wholesome", "milk"]
[x in a_string for x in matches_1]
Out[43]: [True, False, False]
Using word tokenization, "mo" is no longer matched:
[x in tokens for x in matches_2]
Out[44]: [False, False, False]
That is the additional behavior that I wanted. This answer also responds to the duplicate question here.
data = "firstName and favoriteFood"
mandatory_fields = ['firstName', 'lastName', 'age']
# for each
for field in mandatory_fields:
if field not in data:
print("Error, missing req field {0}".format(field));
# still fine, multiple if statements
if ('firstName' not in data or
'lastName' not in data or
'age' not in data):
print("Error, missing a req field");
# not very readable, list comprehension
missing_fields = [x for x in mandatory_fields if x not in data]
if (len(missing_fields)>0):
print("Error, missing fields {0}".format(", ".join(missing_fields)));

Python irregular loop

I'm looking for an elegant 'Pythonic' way to loop through input in groups of a certain size. But the size of the groups vary and you don't know the size of a particular group until you start parsing.
Actually I only care about groups of two sizes. I have a large sequence of input which come in groups of mostly size X but occasionally size Y. For this example lets say X=3 and Y=4 (my actual problem is X=7 and Y=8). I don't know until mid-way through the group of elements if it's going to be a group of size X or of size Y elements.
In my problem I'm dealing with lines of input but to simplify I'll illustrate with characters.
So if it's a group of a particular size I know I'll always get input in the same sequence. So for example if it's a size X group I'll be getting elements of type [a,a,b] but if it's a size Y group I'll be getting elements of type [a,a,c,b]. f it's something of type 'a' I'll want to process it in a certain way and 'b' another etc.
Obviously I have to test an element at some point to determine if it's of type one group or the other. As demonstrated above I cannot just check the type of every element because there may be two of the same in sequence. Also the groups may be the same pattern at the start and only differ near the end. In this example the earliest I can check if I'm in a size X or size Y group is by testing the 3rd element (to see if it's of type 'c' or type 'b').
I have a solution with a for loop with an exposed index and two extra variables, but I'm wondering if there is a more elegant solution.
Here is my code. I've put pass statements in place of where I would do the actual parsing depending on what type it is:
counter = 0
group = 3
for index, x in enumerate("aabaabaacbaabaacbaabaab"):
column = index - counter;
print(str(index) + ", " + x + ", " + str(column))
if column == 0:
pass
elif column == 1:
pass
elif column == 2:
if x == 'c':
pass
elif x == 'd':
group = 4
elif column == 3:
pass
if column + 1 == group:
counter += group
group = 3
In the code example the input stream is aabaabaacbaabaacbaabaab so that is groups of:
aab (3)
aab (3)
aacb (4)
aab (3)
aacb (4)
aab (3)
aab (3)
I would use a generator that collect these groups and determines the size for each, and then ultimately yields each group:
def getGroups (iterable):
group = []
for item in iterable:
group.append(item)
if len(group) == 3 and group[2] == 'c':
yield group
group = []
elif len(group) == 4 and group[2] == 'd':
yield group
group = []
for group in getGroups('abcabcabdcabcabdcabcabc'):
print(group)
['a', 'b', 'c']
['a', 'b', 'c']
['a', 'b', 'd', 'c']
['a', 'b', 'c']
['a', 'b', 'd', 'c']
['a', 'b', 'c']
['a', 'b', 'c']
Looks like you need a simple automata with backtracking, for example:
def parse(tokens, patterns):
backtrack = False
i = 0
while tokens:
head, tail = tokens[:i+1], tokens[i+1:]
candidates = [p for p in patterns if p.startswith(head)]
match = any(p == head for p in candidates)
if match and (backtrack or len(candidates) == 1 or not tail):
yield head
tokens = tail
backtrack = False
i = 0
elif not candidates:
if not i or backtrack:
raise SyntaxError, head
else:
backtrack = True
i -= 1
elif tail:
i += 1
else:
raise SyntaxError, head
tokens = 'aabaabcaabaabcxaabxxyzaabx'
patterns = ['aab', 'aabc', 'aabcx', 'x', 'xyz']
for p in parse(tokens, patterns):
print p
With your particular example, you could use a regex:
>>> s="aabaabaacbaabaacbaabaab"
>>> re.findall(r'aac?b', s)
['aab', 'aab', 'aacb', 'aab', 'aacb', 'aab', 'aab']
If you want a parser that does the same thing, you can do:
def parser(string, patterns):
patterns=sorted(patterns, key=len, reverse=True)
i=0
error=False
while i<len(string) and not error:
for pat in patterns:
j=len(pat)
if string[i:i+j]==pat:
i+=j
yield pat
break
else:
error=True
if error or i<len(string):
raise SyntaxWarning, "Did not match the entire string"
>>> list(parser(s, ['aab', 'aacb']))
['aab', 'aab', 'aacb', 'aab', 'aacb', 'aab', 'aab']

building a boolean dictionary from 2 lists in python

I'm trying to make a dictionary with values 'True' or 'False' when comparing elements in 2 lists. This is probably a bit basic but I'm new to coding and I don't understand why it always assigns the 'True' value even though I can see its not true:
letters = [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z]
randomData = []
f = open('randomData.txt', 'r')
for line in f:
randomData.append(line.rstrip().split()[0])
f.close()
The 'randomData.txt' file looks like:
A'\t'0003'\t'0025'\t'chr1
B'\t'0011'\t'0021'\t'chr7
D'\t'0043'\t'0068'\t'chr3
F'\t'0101'\t'0119'\t'chr7
The randomData list should now look like:
['A','B','D','F']
I tried:
sameLetters = {}
i=0
while i < len(letters):
if letters[i] and randomData:
#append to dictionary
sameLetters[letters[i]] = 'True'
else:
#append to dictionary
sameLetters[letters[i]] = 'False'
i=i+1
print sameLetters
I expected something like:
{'A': 'True', 'B': 'True', 'C': 'False', 'D': 'True', 'E': 'False', 'F': 'True', 'G': 'False', etc
Instead all values in the dictionary are 'True'. Can anyone see the problem? Or give any pointers or explanations? Any help would be great, many thanks.
Perhaps you meant if letters[i] in randomData
I think you want to do something like:
sameLetters = {l: l in randomData for l in letters}
Your current attempt doesn't work because you check
if letters[i] and randomData:
# ^ should be in
and Python interprets both non-empty strings (letters[i]) and non-empty lists (randomData) as True.
Also, note that letters is already available in Python:
from string import ascii_uppercase
This is a string, but you can iterate through and index a string just like a list, and in will still work.
Seems like you only care about which letter appears in your random data, so why not use a set?
from string import ascii_uppercase
randomData = ['A', 'B', 'D', 'F', 'A']
appeared = set(ascii_uppercase).intersection(set(randomData))
print appeared
And later you can us it like this:
char = 'z'
if char in appeared:
print 'yes'
else:
print 'no'
EDIT:
Then how about this:)
from string import ascii_uppercase
randomData = ['A', 'B', 'D', 'F', 'A']
appeared = set(ascii_uppercase).intersection(set(randomData))
d = dict(zip(ascii_uppercase, (False,) * 26))
for key in appeared:
d[key] = True
print d

Categories