Home > Software engineering >  Passing string for variable name Python
Passing string for variable name Python

Time:02-18

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"

CodePudding user response:

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.

CodePudding user response:

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.

CodePudding user response:

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)

CodePudding user response:

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