Assign a Range of Numbers to a Single Key with Dictionaries - python

I was working on a dictionary, but I came up with an issue. And the issue is, I want to be able to use more than 1 number in order to reference a key in a dictionary.
For example, I want the range of numbers between 1 and 5 to be all assigned to, let's say, "apple". So I came up with this:
my_dict['apple'] = range(1,5)
At the program's current state, its far from being able to run, so testing is an issue, but I do not receive any issues from my editor. I was just wondering, is this the correct way to go about this? Or is there a better way?
Thanks.
EDIT:
A little more info: I want to make a random integer with the randint function. Then, after Python has generated that number, I want to use it to call for the key assigned to the value of the random integer. Thing is, I want to make some things more common than others, so I want to make the range of numbers I can call it with larger so the chance of the key coming up becomes likelier. Sorry if it doesn't make much sense, but at the current state, I really don't even have code to show what I'm trying to accomplish.

You have the dictionary backwards. If you want to be able to recall, e.g., 'apple' with any of the numbers 1-5, you'd need the numbers to be the keys, not the values.
for i in range(1,6): # range(a,b) gives [a,b)
my_dict[i] = 'apple'
etc. Then, my_dict[4] == 'apple' and the same is true for the other values in the range.
This can create very large dictionaries with many copies of the same value.
Alternately, you can use range objects as dictionary keys, but the testing will be a bit more cumbersome unless you create your own class.
my_dict[range(1,6)] = 'apple'
n = random.randint(1, 5)
for key in my_dict:
if n in key:
print(my_dict[key])
...prints apple.

The value in a dictionary can be any arbitrary object. Whether it makes sense to use a given type or structure as a value only makes sense in the context of the complete script, so it is impossible to tell you whether it is the correct solution with the given information.

Related

Remove A Specific Instance of a Partially Duplicated Entry In a List In Python 3

I am relatively new to Python. However, my needs generally only involve simple string manipulation of rigidly formatted data files. I have a specific situation that I have scoured the web trying to solve and have come up blank.
This is the situation. I have a simple list of two-part entires, formatted like this:
name = ['PAUL;25', 'MARY;60', 'PAUL;40', 'NEIL;50', 'MARY;55', 'HELEN;25', ...]
And, I need to keep only one instance of any repeated name (ignoring the number to the right of the ' ; '), keeping only the entry with the highest number, along with that highest value still attached. So the answer would look like this:
ans = ['MARY;60', 'PAUL;40', 'HELEN;25', 'NEIL;50, ...]
The order of the elements in the list is irrelevant, but the format of the ans list entries must remain the same.
I can probably figure out a way to brute force it. I have looked at 2D lists, sets, tuples, etc. But, I can't seem to find the answer. The name list has about a million entries, so I need something that is efficient. I am sure it will be painfully easy for some of you.
Thanks for any input you can provide.
Cheers.
alkemyst
Probably the best data structure for this would be a dictionary, with the entries split up (and converted to integer) and later re-joined.
Something like this:
max_score = {}
for n in name:
person, score_str = n.split(';')
score = int(score_str)
if person not in max_score or max_score[person] < score:
max_score[person] = score
ans = [
'%s;%s' % (person, score)
for person, score in max_score.items()
]
This is a fairly common structure for many functions and programs: first convert the input to an internal representation (in this case, split and convert to integer), then do the logic or calculation (in this case, uniqueness and maximum), then convert to the required output representation (in this case, string separated with ;).
In terms of efficiency, this code looks at each input item once, then at each output item once; there's unlikely to be any approach that can do better than that (certainly not formally, and likely not in practice). All of the per-item operations are constant-time and fast. It accumulates the intermediate answer in memory (in max_score), but again that is unavoidable; if memory is an issue, the input and output could be changed to iterators/generators, but the whole intermediate answer has to be accumulated in max_score before any items can be output.

How can I structure variables more efficiently in Python?

Sorry if the title is not so specific. I am looking to restructure variables and if-statements in a program to make the code more efficient. The current code is pretty large and I am sure it can be shortened by at least 70%.
I just started learning Python two weeks ago, I may be missing basic functions that are pretty obvious.
Here is the code:
def function():
variable = int(input('Input: ')
if variable == 10:
variable = 1
elif variable == 9:
variable = 0.9
If I want to repeat this with different values and variables it gets pretty long, and this is what I want to fix.
A friend told me to use dictionaries to store the values but I am not sure how to use if-statements with dictionary values.
How should I structure my code to make it shorter?
At least for the 10 and 9, you are dividing variable by 10. So its better to write it that way instead of writing it explicitly. Also, you can combine the 2 cases in one if case then.
This will shorten the code a bit.
def function():
variable = int(input('Input: '))
if variable == 10 || variable == 9:
variable /= 10
Thank you all for your answers, the solution was easier than I expected and now I feel dumb for not knowing before.
def probeNew():
variable = int(input('Input: '))
output = variable/6.666667
print(output)
probeNew()
Instead of writing all of the fixed values for each input, I just make a formula for whatever result I want from the input. (I know, extremely obvious and easy)
If you want to implement a lookup logic clearly, use dict structure to save key/value pairs.
The key usually be a string, and value can be any others type, like string, integer, etc.
In your case, you can setup the lookup_table={"10":1,"9":0.9},
and get the value by a key, for example, variable = lookup_table[str(10)]
lookup_table={"variable":"value1","variable2":2}
variable = lookup_table[variable]

Error in selecting random item from Dictionary in python

I wan't to create a program that select 2 random items from two different dictionaries. Now I wan't to check if the sum of those items is equal to the value provided by the User. And i wan't to perform this action until i find 2 random items from different dictionaries that add up to the number entered by the User.
Here is what i tried to do:
import random
credit=int(raw_input("Please enter your amount: "))
food=dict([(10, 'Lays'), (10,'Pepsi'), (10,'Burger')])
toys=dict([(10, 'Car'), (10,'Train'), (10,'Chess')])
ranf=random.choice(food.keys())
rant=random.choice(toys.keys())
while int(ranf)+int(rant)!=credit:
ranf=random.choice(food.keys())
rant=random.choice(toys.keys())
print(ranf)
print(food[ranf])
print(rant)
print(food[rant])
When i try to run this code it fails to print those two random items. I'm not getting any error message. Please run this code and help me out.
Thank You
The problem lies within the fact, that you create your dictionaries with duplicate keys - effectively, your food dictionary contains only (10,'Burger') and your toys dictionary has only (10,'Chess') item (they both contain only most recently added item, which replaced all the previous ones). The simplest and quickest fix would be to abandon the usage of a dictionary:
import random
credit=20
food=[(10, 'Lays'), (10,'Pepsi'), (10,'Burger')]
toys=[(10, 'Car'), (10,'Train'), (10,'Chess')]
ranf=random.choice(food)
rant=random.choice(toys)
while int(ranf[0])+int(rant[0])!=credit:
ranf=random.choice(food)
rant=random.choice(toys)
print(ranf)
print(rant)
food.keys() only returns unique keys. So, essentially the only list of keys returned by the food.keys() function is [10].
ex if you make a dictionary like food = dict([(10, 'Lays'), (15,'Pepsi'), (15,'Burger')])
then the list returned by food.keys() will be [10,15] and not [10,15,15] which is what you expect. So, in your code, if ranf = 10, then interpreter takes up the latest value assigned to that key.
Therefore, the random.choice() you are using goes in vain.
Also, there is a silly mistake in your code, you wrote print(food[rant]) instead of writing print(toys[rant]).
It would be better if you don't use a list, otherwise, make the keys different.

Storing more than one key value in a tuple with python?

I'm new to Python and still learning. I was wondering if there was a standard 'best practice' for storing more than one key value in a tuple. Here's an example:
I have a value called 'red' which has a value of 3 and I need to divide it by a number (say 10). I need to store 3 values: Red (the name), 3 (number of times its divides 10) and 1 (the remainder). There are other values that are similar that will need to be included as well, so this is for red but same results for blue, green, etc. (numbers are different for each label).
I read around and I think way I found was to use nested lists, but I am doing this type of storage for a billion records (and I'll need to search through it so I thought maybe nested anything might slow me down).
I tried to create something like {'red':3:1,...} but its not the correct syntax and I'm considering adding a delimiter in the key value and then splitting it but not sure if that's efficient (such as {'red':3a1,..} then parse by the letter a).
I'm wondering if there's any better ways to store this or is nested tuples my only solution? I'm using Python 2.
The syntax for tuples is: (a,b,c).
If you want a dictionary with multiple values you can have a list as the value: {'red':[3,1]}.
You may want to also consider named tuples, or even classes. This will allow you to name the fields instead of accessing them by index, which will make the code more clear and structured.
I read around and I think way I found was to use nested lists, but I am doing this type of storage for a billion records(and I'll need to search through it so I thought maybe nested anything might slow me down).
If you have a billion records you probably should be persisting the data (for example in a database). You will likely run out of memory if you try to keep all the data in memory at once.
Use tuple. For example:
`('red', 3, 1)`
Perhaps you mean dictionaries instead of tuples?
{'red': [3,1], 'blue': [2,2]}
If you are trying to store key/value pairs the best way would be to store them in a dictionary. And if you need more than one value to each key, just put those values in a list.
I don't think you would want to store such things in a tuple because tuples aren't mutable. So if you decide to change the order of the quotient and remainder (1, 3) instead of (3,1), you would need to create new tuples. Whereas with lists, you could simply rearrange the order.

How to rewrite this Dictionary For Loop in Python?

I have a Dictionary of Classes where the classes hold attributes that are lists of strings.
I made this function to find out the max number of items are in one of those lists for a particular person.
def find_max_var_amt(some_person) #pass in a patient id number, get back their max number of variables for a type of variable
max_vars=0
for key, value in patients[some_person].__dict__.items():
challenger=len(value)
if max_vars < challenger:
max_vars= challenger
return max_vars
What I want to do is rewrite it so that I do not have to use the .iteritems() function. This find_max_var_amt function works fine as is, but I am converting my code from using a dictionary to be a database using the dbm module, so typical dictionary functions will no longer work for me even though the syntax for assigning and accessing the key:value pairs will be the same. Thanks for your help!
Since dbm doesn't let you iterate over the values directly, you can iterate over the keys. To do so, you could modify your for loop to look like
for key in patients[some_person].__dict__:
value = patients[some_person].__dict__[key]
# then continue as before
I think a bigger issue, though, will be the fact that dbm only stores strings. So you won't be able to store the list directly in the database; you'll have to store a string representation of it. And that means that when you try to compute the length of the list, it won't be as simple as len(value); you'll have to develop some code to figure out the length of the list based on whatever string representation you use. It could just be as simple as len(the_string.split(',')), just be aware that you have to do it.
By the way, your existing function could be rewritten using a generator, like so:
def find_max_var_amt(some_person):
return max(len(value) for value in patients[some_person].__dict__.itervalues())
and if you did it that way, the change to iterating over keys would look like
def find_max_var_amt(some_person):
dct = patients[some_person].__dict__
return max(len(dct[key]) for key in dct)

Categories

Resources