Passing string for variable name Python - python

I am writing a program that can take in three numbers and three letters on seperate lines. The program will then seperate the numbers into items of a list and will do the same for the letters in a separate list. The program will then sort the the numbers from lowest to highest. I then want to assign the numbers to letters (In a sorted letter order (I.E. A=5, B=16, C=20) and then print the letters in the order it came in from the input (I.E. Input: CAB, output: 20 5 16). I have been able to sort the variables and can do all of this with if statements and for loops but I feel like there is a prettier and more efficient way of doing this. I want to be able to take the input letter string that's divided by use of a list and format the string to insert the variables in the correct order. I know that the globals() and locals() functions do something similar to this but can not figure out how to use them. Any ideas?
Working code:
nput_numbers_list = ((input()).split(" "))
input_letters = (input())
input_letters_list = []
for i in range(3):
input_letters_list.append(input_letters[i])
input_numbers_list = [int(x) for x in input_numbers_list]
input_numbers_list.sort()
print_string = ""
for i in range(3):
if input_letters[i] == "A":
print_string = print_string + A + " "
if input_letters[i] == "B":
print_string = print_string + B + " "
if input_letters[i] == "C":
print_string = print_string + C + " "
print(print_string)
My (wanted) code:
input_numbers_list = ((input()).split(" "))
input_letters = (input())
input_letters_list = []
for i in range(3):
input_letters_list.append(input_letters[i])
input_numbers_list = [int(x) for x in input_numbers_list]
input_numbers_list.sort()
A = str(input_numbers_list[0])
B = str(input_numbers_list[1])
C = str(input_numbers_list[2])
final_list = ["""Magic that turns input_letters_list into variables in the order used by list and then uses that order"""]
print("{} {} {}".format("""Magic that turns final_list into variables in the order used by list and then puts it in string""")
Wanted/expected input and output:
Input: "5 20 16"
Input: "CAB"
Output: "20 5 16"

As others have suggested, you will likely want an answer that uses a dictionary to lookup numbers given letters.
##----------------------
## hardcode your input() for testing
##----------------------
#input_numbers = input()
#input_letters = input()
input_numbers = "5 20 16"
input_letters = "CAB"
input_numbers_list = input_numbers.split(" ")
input_letters_list = list(input_letters) # not technically needed
##----------------------
##----------------------
## A dictionary comprehension
# used to construct a lookup of character to number
##----------------------
lookup = {
letter: number
for letter, number
in zip(
sorted(input_letters_list),
sorted(input_numbers_list, key=int)
)
}
##----------------------
##----------------------
## use our original letter order and the lookup to produce numbers
##----------------------
result = " ".join(lookup[a] for a in input_letters_list)
##----------------------
print(result)
This will give you your requested output of:
20 5 16
There is a lot going on with the construction of the dictionary lookup, so let's unpack it a bit.
First of, it is based on calling zip(). This function takes two "lists" and pairs their elements up creating a new "list". I use "list" in quotes as it is more like iterables and generators. Anyways. let's take a closer look at:
list(zip(["a","b","c"], ["x","y","z"]))
this is going to give us:
[
('a', 'x'),
('b', 'y'),
('c', 'z')
]
So this is how we are going to pairwise combine our numbers and letters together.
But before we do that, it is important to make sure that we are going to pair up the "largest" letters with the "largest" numbers. To ensure that we will get a sorted version of our two lists:
list(
zip(
sorted(input_letters_list), #ordered by alphabet
sorted(input_numbers_list, key=int) #ordered numerically
)
)
gives us:
[
('A', '5'),
('B', '16'),
('C', '20')
]
Now we can feed that into our dictionary comprehension (https://docs.python.org/3/tutorial/datastructures.html).
This will construct a dictionary with keys of our letters in the above zip() and values of our numbers.
lookup = {
letter: number
for letter, number
in zip(
sorted(input_letters_list),
sorted(input_numbers_list, key=int)
)
}
print(lookup)
Will give us our lookup dictionary:
{
'A': '5',
'B': '16',
'C': '20'
}
Note that our zip() technically gives us back a list of tuples and we could also use dict() to cast them to our lookup.
lookup = dict(zip(
sorted(input_letters_list),
sorted(input_numbers_list, key=int)
))
print(lookup)
also gives us:
{
'A': '5',
'B': '16',
'C': '20'
}
But I'm not convinced that clarifies what is going on or not. It is the same result though so if you feel that is clearer go for it.
Now all we need to do is go back to our original input and take the letters one by one and feed them into our lookup to get back numbers.
Hope that helps.

Its very weird the case when you need to conver string to a variable, when you feel that you need something like that a dictionary will probably do the trick.
in this case the solution can be done with the following code.
input_numbers_list = (("5 20 16").split(" "))
input_letters = ("CAB")
input_letters_list = [letter for letter in input_letters]
input_numbers_list = [int(x) for x in input_numbers_list]
rules = {}
for letter, value in zip(input_letters_list, input_numbers_list):
rules[value] = letter
output = ""
input_numbers_list.sort()
for numb in input_numbers_list:
output += rules[numb] + " "
print(output)
And you can use it for n inputs and outputs.
The idea of a dictionary is that you have keys, and values, so for a key (in this case text of letters) you can get a value, similar to a variable. Plus is super fast.

You could use a dictionary for that! https://www.w3schools.com/python/python_dictionaries.asp
EDIT: the output is more consistent with the requested one, but it should be "20 16 5" instead of "20 5 16" if I understood your problem well.
input_numbers_list = input().split(" ")
input_letters = input()
# Create new dictionary
input_dict = {}
# Fill it by "merging" both lists
for index, letter in enumerate(input_letters):
input_dict[letter] = input_numbers_list[index]
# Sort it by converting it into a list and riconverting to dict
sorted_dict = {k: v for k, v in sorted(list(input_dict.items()))}
# Print the result
output = ''
for value in sorted_dict.values():
output += value + ' '
print(output)

Using zip function helps
num_arr = list(map(int,input().split(' ')))
word = input()
num_arr.sort()
word = sorted(word)
mapper = dict(zip(word,num_arr))
result = ' '.join(map(str,[mapper[i] for i in word]))
print(result)

Related

Take substring from dictionary value

I have a dictionary containing variables and their values.
This is my dictionary, for example:
{27: 'choice = input("Enter choice(1/2/3/4): ")',
31: 'num1 = float(input("Enter first number: "))',
32: 'num2 = float(input("Enter second number: "))',
48: 'next_calculation = input("Let\'s do next calculation? (yes/no): ")'}
and I want to go over values in the dictionary and save a substring of the string in the list.
The output should look like this from the previous dict:
list = ['choice','num1','num2','next_calculation']
How can I do this?
Use a list comprehension. Assuming d the input dictionary.
lst = [x.split()[0] for x in d.values()]
output: ['choice', 'num1', 'num2', 'next_calculation']
NB. do not name your variable list, this is a python builtin
If you have a very long string or want to explicitly define a different separator, use:
lst = [x.split(sep=' = ', maxsplit=1)[0] for x in d.values()]

Creating python dictionaries using for loop

I make a bunch of matrices that I want to store in python dictionaries and I always find myself typing the same thing for every state that I want to build, i.e.
Ne21_1st_state = {}
Ne21_2nd_state = {}
Ne21_3rd_state = {}
Ne21_4th_state = {}
Ne21_5th_state = {}
Ne21_6th_state = {}
...
Ne21_29th_state = {}
Ne21_30th_state = {}
Can somebody help me automate this using python for loops?
Thanks in advance!
I want something like this:
for i in range(3, 11):
states = f'Ar36_{i}th_state'
print(states)
where the output would be:
Ar36_3th_state
Ar36_4th_state
Ar36_5th_state
Ar36_6th_state
Ar36_7th_state
Ar36_8th_state
Ar36_9th_state
Ar36_10th_state
but instead of printing it it would create individual dictionaries named Ar36_3th_state, Ar36_4th_state, Ar36_5th_state, ...
can't we make a List of dictionaries
List of 30 (or any N) elements where each element is a dictionary with key = "Ar36_{i}th_state" and value = {whatever value you want}
You can create "name" of pseudo variable and use it as key in dictionary like:
my_dic = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}
my_empty_dic = {}
solution = {}
for i in range(1, 31):
name = 'Ne21_'+str(i)+'st_state'
#solution[name] = my_dic
solution[name] = my_empty_dic
for pseudo_variable in solution:
print(pseudo_variable, solution[pseudo_variable])
print(solution['Ne21_16st_state'])
for pseudo_variable in solution:
if '_16st' in pseudo_variable:
print(pseudo_variable, solution[pseudo_variable])
One way I've done this is using list comprehension.
key = list(
str(input(f"Please enter a Key for value {x + 1}: "))
if x == 0
else str(input(f"\nPlease enter a Key for value {x + 1}: "))
for x in range(3))
value = list(str(input(f"\nPlease enter a Bool for value {x + 1}: "))
for x in range(3))
BoolValues = dict(zip(key, value))
I first create a list of keys followed by a list of the values to be stored in the keys. Then I just zip them together into a dictionary. The conditional statements in the first list are only for a slightly better user-experience with \n being added if it's passed the first input.
Actually now that I look back on the question it may be slightly different to what I was thinking, are you trying to create new dictionaries for every matrix? If that is the case, is it something similar to this?: How do you create different variable names while in a loop?

Print meaning of first letter

If I have a list like:
Q = Quiet
J = John
I want to print the meaning of the first letter in:
Queer
Johnson
How do I do that? I want to take the meaning of Q from Queer and J from Johnson and print it in list form.
Output:
Quiet
John
handleNameChange(name):
if(name[0] == 'Q'):
print("Quiet");
else:
print("John");
a = input()
b = input()
handleNameChange(a);
handleNameChange(b)
Input:
Queer
Johnson
Output:
Quiet
John
meaning = {'Q': 'Quiet', 'J': 'John'}
user_input = 'Queer Johnson'
result_list = list(map(lambda x: meaning[x[0]], user_input.split()))
print(result_list)
Output
['Quiet', 'John']
Your question is very unclear, but I'll make an assumption that you actually need a dictionary, rather than a list, in order to create a "pseudo" translator of sorts
dictionary = {'Q': 'Quiet', 'J':'John'}
Subsequently, I assume you'd like to extract capital letters from your string, which can be done by using regex (one of many solutions)
import re
string = "Queer Johnson"
capital_letters = re.findall(r'[A-Z]', string)
Output:
['Q','J']
You can then use the dictionary to "translate" extracted letters
results = [v for i in capital_letters for k,v in dictionary.items() if i == k]
Output:
['Quiet', 'John']
P.S. Make sure your questions are properly constructed. It will help both you and the community.
Cheers!

Counting only the frequency of letters in a string

I am trying to make my program count everything but numbers in a string, and store it in a dictionary.
So far I have this:
string = str(input("Enter a string: "))
stringUpper = string.upper()
dict = {}
for n in stringUpper:
keys = dict.keys()
if n in keys:
dict[n] += 1
else:
dict[n] = 1
print(dict)
I just want the alphabetical numbers quantified, but I cannot figure out how to exclude the non-alphabetical characters.
Basically there are multiple steps involved:
Getting rid of the chars that you don't want to count
Count the remaining
You have several options available to do these. I'll just present one option, but keep in mind that there might be other (and better) alternatives.
from collections import Counter
the_input = input('Enter something')
Counter(char for char in the_input.upper() if char.isalpha())
For example:
Enter something: aashkfze3f8237rhbjasdkvjuhb
Counter({'A': 3,
'B': 2,
'D': 1,
'E': 1,
'F': 2,
'H': 3,
'J': 2,
'K': 2,
'R': 1,
'S': 2,
'U': 1,
'V': 1,
'Z': 1})
So it obviously worked. Here I used collections.Counter to count and a generator expression using str.isalpha as condition to get rid of the unwanted characters.
Note that there are several bad habits in your code that will make your life more complicated than it needs to be:
dict = {} will shadow the built-in dict. So it's better to choose a different name.
string is the name of a built-in module, so here a different name might be better (but not str which is a built-in name as well).
stringUpper = string.upper(). In Python you generally don't use camelCase but use _ to seperate word (i.e. string_upper) but since you only use it to loop over you might as well use for n in string.upper(): directly.
Variable names like n aren't very helpful. Usually you can name them char or character when iterating over a string or item when iterating over a "general" iterable.
You can use re to replace all non-alphabetical characters before doing any manipulation:
regex = re.compile('[^a-zA-Z]')
#First parameter is the replacement, second parameter is your input string
regex.sub('', stringUpper )
string = str(input("Enter a string: "))
stringUpper = string.upper()
dict = {}
for n in stringUpper:
if n not in '0123456789':
keys = dict.keys()
if n in keys:
dict[n] += 1
else:
dict[n] = 1
print(dict)
for n in stringUpper:
if n.isalpha()
dict[n] += 1
else:
dict[n] = 1
print(dict)
You can check string for alphanumeric
n.isalnum()
for aphabetic:
n.isalpha()
So your code will be like:
dict = {}
for n in stringUpper:
if n.isalpha():
keys = dict.keys()
if n in keys:
dict[n] += 1
else:
dict[n] = 1
print(dict)
else:
#do something....
While iterating, check if the lower() and upper() is the same for a character. If they are different from each other, then it is an alphabetical letter.
if n.upper() == n.lower():
continue
This should do it.

Creating and rearranging a dictionary

I am new to python! I have created a code which successfully opens my text file and sorts my list of 100's of words. I then have put these in a list labelled stimuli_words, which consists of no duplicates words, all lower case etc.
However I now want to convert this list into a dictionary, where the keys are all possible 3 letter endings in my list of words, and the values are the words that correspond to those endings.
For instance 'ing: going, hiring...', but I only want the words in which have more than 40 words corresponding to the last two characters. So far I have this code:
from collections import defaultdict
fq = defaultdict( int )
for w in stimuli_list:
fq[w] += 1
print fq
However it is just returning a dictionary with my words and how many times they occur which is obviously once. e.g 'going': 1, 'hiring': 1, 'driving': 1.
Really would appreciate some help!! Thank You!!
You could do something like this:
dictionary = {}
words = ['going', 'hiring', 'driving', 'letter', 'better', ...] # your list or words
# Creating words dictionary
for word in words:
dictionary.setdefault(word[-3:], []).append(word)
# Removing lists that contain less than 40 words:
for key, value in dictionary.copy().items():
if len(value) < 40:
del dictionary[key]
print(dictionary)
Output:
{ # Only lists that are longer than 40 words
'ing': ['going', 'hiring', 'driving', ...],
'ter': ['letter', 'better', ...],
...
}
Since you're counting the words (because your key is the word), you only get 1 count per word.
You could create a key of the 3 last characters (and use Counter instead):
import collections
wordlist = ["driving","hunting","fishing","drive","a"]
endings = collections.Counter(x[-3:] for x in wordlist)
print(endings)
result:
Counter({'ing': 3, 'a': 1, 'ive': 1})
Create DemoData:
import random
# seed the same for any run
random.seed(10)
# base lists for demo data
prae = ["help","read","muck","truck","sleep"]
post= ["ing", "biothign", "press"]
# lots of data
parts = [ x+str(y)+z for x in prae for z in post for y in range(100,1000,100)]
# shuffle and take on ever 15th
random.shuffle(parts)
stimuli_list = parts[::120]
Creation of dictionary from stimuli_list
# create key with empty lists
dic = dict(("".join(e[len(e)-3:]),[]) for e in stimuli_list)
# process data and if fitting, fill list
for d in dic:
fitting = [x for x in parts if x.endswith(d)] # adapt to only fit 2 last chars
if len(fitting) > 5: # adapt this to have at least n in it
dic[d] = fitting[:]
for d in [x for x in dic if not dic[x]]: # remove keys with empty lists
dic.remove(d)
print()
print(dic)
Output:
{'ess': ['help400press', 'sleep100press', 'sleep600press', 'help100press', 'muck400press', 'muck900press', 'muck500press', 'help800press', 'muck100press', 'read300press', 'sleep400press', 'muck800press', 'read600press', 'help200press', 'truck600press', 'truck300press', 'read700press', 'help900press', 'truck400press', 'sleep200press', 'read500press', 'help600press', 'truck900press', 'truck800press', 'muck200press', 'truck100press', 'sleep700press', 'sleep500press', 'sleep900press', 'truck200press', 'help700press', 'muck300press', 'sleep800press', 'muck700press', 'sleep300press', 'help500press', 'truck700press', 'read400press', 'read100press', 'muck600press', 'read900press', 'read200press', 'help300press', 'truck500press', 'read800press']
, 'ign': ['truck200biothign', 'muck500biothign', 'help800biothign', 'muck700biothign', 'help600biothign', 'truck300biothign', 'read200biothign', 'help500biothign', 'read900biothign', 'read700biothign', 'truck400biothign', 'help300biothign', 'read400biothign', 'truck500biothign', 'read800biothign', 'help700biothign', 'help400biothign', 'sleep600biothign', 'sleep500biothign', 'muck300biothign', 'truck700biothign', 'help200biothign', 'sleep300biothign', 'muck100biothign', 'sleep800biothign', 'muck200biothign', 'sleep400biothign', 'truck100biothign', 'muck800biothign', 'read500biothign', 'truck900biothign', 'muck600biothign', 'truck800biothign', 'sleep100biothign', 'read300biothign', 'read100biothign', 'help900biothign', 'truck600biothign', 'help100biothign', 'read600biothign', 'muck400biothign', 'muck900biothign', 'sleep900biothign', 'sleep200biothign', 'sleep700biothign']
}

Categories