How to get value for each string index matching key in dictionary in Python - string

str = 'strings'
new_D = {'r': 1, 's': 1, 't': 1, 'r' : 3, 'i' : 4 }
How can I get each letter in the string assigned to the value in the dictionary by match 'letter-key' and then summarize the values?
Thanks

s = 'strings' #Don't name a variable str, that shadows the builtin str
new_D = {'r': 1, 's': 1, 't': 1, 'r' : 3, 'i' : 4 }
sum_of_chars = sum([newD.get(k,0) for k in s]) #assuming 0 as default for "not in dictionary"
This takes advantage of the fact that:
Strings are iterable. for i in s: print(i) would print each character, seperately.
Dictionaries have a .get(key[,default]) 1 that can take an option argument for "return this value if the key doesn't exist.
I'm using the built-in sum on a list comprehension for the sake of brevity. Brevity can both be a virtue or a vice, but, hey, one list comp is still usually pretty readable after you know what they are.

string = 'strings'
new_D = {'r': 1, 's': 1, 't': 1, 'r' : 3, 'i' : 4 }
sum_of_chars = 0
for character in string:
if character in new_D:
sum_of_chars += new_D[character]
else:
sum_of_chars += 1 # Default?
print(sum_of_chars)
btw, you should not use the name str because it shadows the builtin str and there's a mistake in your dictionary. It contains the entry r two times which doesn't make sense.

Related

What does this mean " first_match = bool(text) and pattern[0] in {text[0], '.'} " ? This is the regular expression matching question in python

def match(text, pattern):
if not pattern: return not text
first_match = bool(text) and pattern[0] in {text[0], '.'}
return first_match and match(text[1:], pattern[1:])
I'm new to python and I don't understand the syntax. What is the purpose of elements in braces and what does "bool(text) and pattern[0] in {text[0], '.'}"
In python, braces are used to create either a dictionary, or a set.
my_set = {1, 2, 3}
my_dict = {'a': 1, 'b': 2, 'c': 3}
bool(text) and pattern[0] in {text[0], '.'} is checking whether the text is true (i.e. not empty or false), and the first element in pattern is either equal to text[0] or is a '.'
If we were to destruct your function into distinct pieces, it will be easier to understand
def match(text: str, pattern: str) -> bool:
# if pattern is an empty string or None
if not pattern:
# True if text is empty string or None, otherwise - false
result: bool = not text
return result
# If text is empty or None return False
if not text:
return False
# Equivalent to set(first letter of text, dot)
# We use set/{} instead of list/[] or tuple/() to remove duplicates,
# however i don't see why should we care about duplicated dots here
subset: set = {text[0], '.'}
# If first letter of pattern is not in subset, return False
if pattern[0] not in subset:
return False
# Go one level deeper in recursion and return it's answer
result: bool = match(text[1:], pattern[1:])
return result
About curly braces. In python they mean two things:
dict / dictionary: {"foo": "bar", "count": 10}
set / unique list: {1, 2, 3, 3} will create set {1, 2, 3}
Follow the links to learn more from python's docs

How do I find character frequency form text file through iteration? (python3)

I'm trying to find a way to iterate through a text file and list to find character frequency. I understand that I could use Count() for this. But Count() gives everything including spaces periods and whatnots. Also it does not show the character frequency in alphabetical order. I found a way to do it and it works but not really. I'll explain later. Also when I try to put the frequency I get a KeyError. I'll also explain.
I don't want to put my whole project on here so I'll explain some stuff first. I have a separate list called alphabet_list which includes the alphabet. There's a text file that is already read through and converted into uppercase called new_text.
Character frequency Code:
for i in range(len(alphabet_list)):
for c in new_text:
if c == alphabet_list[i]:
count += 1
else:
count = 0
print(alphbet_list[i] + " " + str(count)
i += 1
Output
A 0
A 0
.
.
.
A 1
A 0
.
.
.
B 0
.
.
.
B 1
B 2
B 0
.
.
.
Z 0
P.S the str(count) is temporarily there because I want to see how it looks like print out, I needed to store the result in dictionary
My output would be that, like I said it works but not really. It will iterate but it iterates through every letter and prints out the result already and does not iterate the whole text file and just print final result. It will add to the result if there is another letter same as before right next to each other. Ex (... bb...) it will be B 1, B 2 like shown in my output. And for some reason when I use return it doesn't work. It returns nothing and just ends the program.
Second Code with KeyError:
I skipped the problem on top because I couldn't find the answer and didn't want to waste my time but ran into another problem lol*
for i in range(len(alphabet_list)):
for c in new_text:
if c == alphabet_list[i]:
count += 1
else:
count = 0
c_freq[alphabet_list[i]] == count
print(c_freq)
i += 1
This one was pretty simple I got a KeyError: 'A'.
I tried only doing the
i = 3 #just random number to test
count = 50
c_freq[alphabet_list[i]] == count
print(c_freq)
and it works, so I'm thinking that problem is also related to the problem above(? maybe). Anyways any help would be great. Thanks!
Sorry for long question but I really needed help.
This should help you:
lst = ['A', 'Z', 'H', 'A', 'B', 'N', 'H', 'Y', '.' , ',','Z'] #Initial list. Note: The list also includes characters such as commas and full stops.
alpha_dict = {}
for ch in lst:
if ch.isalpha(): #Checks if the character is an alphabet
if ch in alpha_dict.keys():
alpha_dict[ch] += 1 #If key already exists, value is incremented by 1
else:
alpha_dict[ch] = 1 #If key does not exist, a new key is created with value 1
print(alpha_dict)
Output:
{'A': 2, 'Z': 2, 'H': 2, 'B': 1, 'N': 1, 'Y': 1}
Since you want the output to be sorted in alphabetical order, add these lines to your code:
key_list = list(alpha_dict.keys()) #Creates a list of all the keys in the dict
key_list.sort() #Sorts the list in alphabetical order
final_dict = {}
for key in key_list:
final_dict[key] = alpha_dict[key]
print(final_dict)
Output:
{'A': 2, 'B': 1, 'H': 2, 'N': 1, 'Y': 1, 'Z': 2}
Thus, here is the final code:
lst = ['A', 'Z', 'H', 'A', 'B', 'N', 'H', 'Y', '.' , ',','Z']
alpha_dict = {}
for ch in lst:
if ch.isalpha():
if ch in alpha_dict.keys():
alpha_dict[ch] += 1
else:
alpha_dict[ch] = 1
key_list = list(alpha_dict.keys())
key_list.sort()
final_dict = {}
for key in key_list:
final_dict[key] = alpha_dict[key]
print(final_dict)
Output:
{'A': 2, 'B': 1, 'H': 2, 'N': 1, 'Y': 1, 'Z': 2}

What's the one liner to split a string to dictionary with default value in python3?

I have a input string input_str = 'a=1;b=2;c' and I want to split it into dictionary as {'a':1, 'b':2, 'c': '.'}
input_str = 'a=1;b=2;c'
default = '.'
output = dict(s.split('=') if '=' in s else {s ,default} for s in input_str.split(';'))
print(output)
{'a': '1', 'b': '2', '.': 'c'}
# Output I want:
{'a': '1', 'b': '2', 'c': '.'}
Following code works.But I was looking for a one liner with dict comprehension.
my_result = {}
input_str = 'a=1;b=2;c'
for s in input_str.split(';'):
if '=' in s:
key, val = s.split('=')
my_result[key] = val
else:
my_result[s] = '.'
I noticed that else condition in above code {s ,default} is treated as set. How to convert it into dictionary.
As you noted, {s, default} defines a set, and the order of sets is undefined.
All you need to do to remedy this is to use a list instead.
dict(s.split('=', 1) if '=' in s else [s, default] for s in input_str.split(';'))
Note, this is unlikely to be very useful in real-life unless you have very restricted requirements. What happens if you want to include a value that contains a ';' character?
By changing the first split() call to have , 1, this means that the value will only ever be split once, no matter how many '=' characters there are.
For example, trying to parse an input of: a=bad=value;b=2 would raise a ValueError.

How to assign variable name and value to a dictionary as key value pair in python

I would like to take a variable and the variable value and append them to a dictionary:
mydict = {}
myvar = 5
mydict[myvar] = myvar.value
>>> mydict
{myvar : 5}
Any ideas?
As I explained in the comments, this is impossible for arbitrary variables (except of course hard-coding, for example x = 5 ; {'x': x}.
What is possible:
Simply use locals() or dir() but you will get information you (probably) don't care about (such as current file path, imported modules, etc).
Create a dictionary of specific variables while hard-coding their names:
x = 1
y = 2
print({var_name: globals()[var_name] for var_name in ['x', 'y']})
# {'x': 1, 'y': 2}
Use a predefined knowledge about the variables you are searching for. For example, get the names of all defined int and float:
a = 1
b = 2
c = 3.0
print({var_name: var_value for var_name, var_value in globals().items()
if isinstance(var_value, (int, float))})
# {'c': 3.0, 'a': 1, 'b': 2}
If using strings, to prevent existing globals strings from being added, use startswith
{var_name: var_value for var_name, var_value in globals().items() if isinstance(var_value, (str)) and not var_name.startswith("__")}

converting individual digits to string

I think i'm very close but i cant seem to fix my issues. I need a function that takes a 10-digit input from user (me) and sets each letter to is numeric value.
Example: user inputs (941-019-abcd) the function should then take this and return (941-019-2223)
Anything that i should be doing differently please feel free to elaborate
Here is what i have thus far:
def main(phone_number):
digits = ["2", "3", "4", "5", "6", "7", "8", "9"]
numeric_phone=" "
ch = digits[i]
for ch in phone_number:
if ch.isalpha():
elif ch== 'A' or 'b' or 'c':
i=2
elif ch== 'd' or 'e' or 'f':
i=3
elif ch== 'g' or 'h' or 'i':
i=4
elif ch=='j' or 'k' or 'l':
i=5
elif ch== 'm' or 'n' or 'o':
i=6
elif ch== 'p' or 'r' or 's':
i=7
elif ch=='t' or 'u' or 'v':
i=8
else:
index=9
numeric_phone= numeric_phone+ch
print (numeric_phone)
phone_number = '941-019-aBcD'
# A map of what letters to convert to what digits.
# I've added q and wxy & z.
digit_map = {
'abc': 2,
'def': 3,
'ghi': 4,
'jkl': 5,
'mno': 6,
'pqrs': 7,
'tuv': 8,
'wxyz': 9
}
# Break this out into one letter per entry in the dictionary
# to make the actual work of looking it up much simpler.
# This is a good example of taking the data a person might
# have to deal with and making it easier for a machine to
# work with it.
real_map = {}
for letters, number in digit_map.iteritems():
for letter in letters:
real_map[letter] = number
# Empty new variable.
numeric_phone = ''
# For each character try to 'get' the number from the 'real_map'
# and if that key doesn't exist, just use the value in the
# original string. This lets existing numbers and other
# characters like - and () pass though without any special
# handling.
# Note the call to `lower` that converts all our letters to
# lowercase. This will have no effect on the existing numbers
# or other speacial symbols.
for ch in phone_number.lower():
numeric_phone += str(real_map.get(ch, ch))
print(numeric_phone)
def main(phone_number):
digits = ["2", "3", "4", "5", "6", "7", "8", "9"]
numeric_phone=" "
for ch in phone_number:
if ch.isalpha():
if ord(ch) >= 97:
ch = +2 (ord(ch)-97)/3
else:
ch = +2 (ord(ch)-65)/3
numeric_phone= numeric_phone+ch
print (numeric_phone)
Use ord() to convert chars to their ASCII values and then get the right number.
You can create a formula to ascertain the correct number to add depending on the letter:
math.ceil((index(char)+1)/3)
Use a list and depending on which character it is, append a number to the list. At the end, return the list, but joined so that it is a string:
def numerify(inp):
from math import ceil as _ceil
from string import lowercase as _lowercase
chars = []
for char in inp:
if char.isalpha():
num = _ceil((_lowercase.index(char)+1)/float(3))
chars.append(str(int(num+1)))
else:
chars.append(char)
return ''.join(chars)
>>> from numerify import numerify
>>> numerify('1')
'1'
>>> numerify('941-019-abcd')
'941-019-2223'
>>>
I think it's easiest to pre-calculate the number character for each letter.
# len(keys) == 26 so that the index of a letter
# maps to its phone key
keys = ['2']*3 + ['3']*3 \
+ ['4']*3 + ['5']*3 + ['6']*3 \
+ ['7']*4 + ['8']*3 + ['9']*4
def letter_to_key(x):
if x.isalpha():
# calculate the 'index' of a letter.
# a=0, b=1, ..., z=25
index = ord(x.lower()) - ord('a')
return keys[index]
# If it's not a letter don't change it.
return x
def translate_digits(phone_num):
return ''.join(map(letter_to_key, phone_num))
print(translate_digits('941-019-abcd'))

Resources