Python updating dictionary but need to get the key pair? - python-3.x

Given this dictionary format:
name: (id, type1, type2, hp, attack, defense, speed, generation, legendary)
dict={'Bulbasaur': (1, 'Grass', 'Poison', 45, 49, 49, 45, 1, False)}
I need to go through the database (dictionary of multiple pokemon with their stats in the provided format) and find which pokemon have legendary status, which is a boolean value. I need to count the types that are legendary and put them in a new dictionary.
So for example if Bulbasaur was legendary, Grass type=1 Poison type=1. New dictionary item would be :
new_dict={"Grass": 1, "Poison": 1}
I made the code to get the types extracted and then count which types are legendary but I am stuck on how to get the final dictionary with type and count number.
Here is the code that I have:
def legendary_count_of_types(db):
Fire=0
Grass=0
Flying=0
Poison=0
Dragon=0
Water=0
Fighting=0
Ground=0
Ghost=0
Rock=0
Ice=0
d={}
for key,values in db.items():
status=values[8]
if status==True:
type_list=get_types(db)
for item in type_list:
if item=='Fire':
Fire+=1
if item=='Grass':
Grass+=1
if item=='Flying':
Flying+=1
if item=='Poison':
Poison+=1
if item=='Dragon':
Dragon+=1
if item=='Water':
Water+=1
if item=='Fighting':
Fighting+=1
if item=='Ground':
Ground+=1
if item=='Ghost':
Ghost+=1
if item=='Rock':
Rock+=1
if item=='Ice':
Ice+=1
d.update()
#how do I get the key value pair?
return d
Here is what my get_types function does:
def get_types(db):
l=[]
s=[]
for key,values in db.items():
types1=str(values[1])
types2-str(values[2])
l.apppend(types1)
l.append(types2)
for i in l:
if i not in s:
s.append(i)
if 'None' in s:
s.remove('None')
final_list=s
return sorted(final_list)

Assuming you just want a count of the times a type appears in a legendary Pokemon, without using anything fancy like pandas (which you probably ought to be doing with your data collection, or maybe a little sql db)
type_counter = dict() # or use collections.Counter
for name, attributes in db.items()
is_legendary = attributes[8]
if is_legendary:
type1 = attributes[1]
type2 = attributes[2]
type_counter[type1] = type_counter.get(type1, 0) + 1
type_counter[type2] = type_counter.get(type2, 0) + 1
# type_counter will now be a dictionary with the counts.

Related

(Beginner Python assignment help) Search input list

I have just started learning python and i have been given an assignment to create a list of players and stats using different loops.
I cant work out how to create a function that searches the player list and gives an output of the players name and the players stat.
Here is the assignment:
Create an empty list called players
Use two input() statements inside a for loop to collect the name
and performance of each player (the name will be in the form of a
string and the performance as an integer from 0 – 100.) Add both
pieces of information to the list (so in the first iteration of the
loop players[0] will contain the name of the first player and
players[1] will contain their performance.) You are not required to
validate this data.
Use a while loop to display all the player information in the
following form:
Player : Performance
Use a loop type of your choice to copy the performance values from
the players list and store these items in a new list called results
Write a function that accepts the values “max” or “min” and
returns the maximum or minimum values from the results list
Write a function called find_player() that accepts a player name
and displays their name and performance from the players list, or an
error message if the player is not found.
Here is what I have so far:
print ("Enter 11 Player names and stats")
# Create player list
playerlist = []
# Create results list
results = []
# for loop setting amount of players and collecting input/appending list
for i in range(11):
player = (input("Player name: "))
playerlist.append(player)
stats = int(input("Player stats: "))
playerlist.append(stats)
# While loop printing player list
whileLoop = True
while whileLoop == True:
print (playerlist)
break
# for loop append results list, [start:stop:step]
for i in range(11):
results.append(playerlist[1::2])
break
# max in a custom function
def getMax(results):
results = (playerlist[1::2])
return max(results)
print ("Max Stat",getMax(results))
# custom function to find player
def find_player(playerlist):
list = playerlist
name = str(input("Search keyword: "))
return (name)
for s in list:
if name in str(s):
return (s)
print (find_player(playerlist))
I have tried many different ways to create the find player function without success.
I think I am having problems because my list consists of strings and integers eg. ['john', 6, 'bill', 8]
I would like it to display the player that was searched for and the stats ['John', 6]
Any help would be greatly appreciated.
PS:
I know there is no need for all these loops but that is what the assignment seems to be asking for.
Thank you
I cut down on the fat and made a "dummy list", but your find_player function seems to work well, once you remove the first return statement! Once you return something, the function just ends.
All it needs is to also display the performance like so:
# Create player list
playerlist = ["a", 1, "b", 2, "c", 3]
# custom function to find player
def find_player(playerlist):
name = str(input("Search keyword: "))
searchIndex = 0
for s in playerlist:
try:
if name == str(s):
return ("Player: '%s' with performance %d" % (name, playerlist[searchIndex+1]))
except Exception as e:
print(e)
searchIndex += 1
print (find_player(playerlist))
>>Search keyword: a
>>Player: 'a' with performance 1
I also added a try/except in case something goes wrong.
Also: NEVER USE "LIST" AS A VARIABLE NAME!
Besides, you already have an internal name for it, so why assign it another name. You can just use playerlist inside the function.
Your code didn't work because you typed a key and immediately returned it. In order for the code to work, you must use the key to find the value. In this task, it is in the format of '' key1 ', value1,' key2 ', value2, ...]. In the function, index is a variable that stores the position of the key. And it finds the position of key through loop. It then returns list [index + 1] to return the value corresponding to the key.
playerlist = []
def find_player(playerlist):
list = playerlist
name = str(input("Search keyword: "))
index = 0
for s in list:
if name == str(s):
return ("This keyword's value: %d" % (list[index+1]))
index+=1
print (find_player(playerlist))

Add key values to dictionary without key value pairs being associated to one another

I've created a dictionary of different keys and different values. When I update the values for one key, all the values update and are equal. I don't understand why that is. I don't understand why the values of each key are pointing to the same memory location especially when they were created at different times.
I've tried using the update methods.
I've tried assigning values by doing diction['new_value']= 'key_value'.
I've tried the from_keys().
def transform(self, rows):
#Rows are a row from a csv, tsv, or txt file and I'm splitting them by white space, tabs, or commas. I've created an inherited function that does that for me called split_line.
data = self.split_line(rows)
for idx, column in enumerate(data):
if idx != 0:
if self.metadata_types[idx].lower() == 'numeric':
column = round(float(column), 3)
elif self.metadata_types[idx].lower() == 'group':
if column not in self.uniqueValues:
self.uniqueValues.append(column)
annotation =self.header[idx]
self.annotation_subdocs[annotation]['value'].append(column)
def create_annotation_subdocs(self):
annotation_subdocs = dict()
#For ever value in the header I want to create a new dictionary with the key being the header value
for idx, value in enumerate(self.header):
if value == 'name':
self.annotation_subdocs[value]= create_metadata_subdoc('text', idx, 'cells')
print(id(annotation_subdocs[value]))
elif value in ('x', 'y', 'z'):
self.annotation_subdocs[value] = create_metadata_subdoc(value, idx, 'coordinates')
print(id(annotation_subdocs[value]))
else:
self.annotation_subdocs[value]=create_metadata_subdoc(value, idx, 'annotations')
print(id(annotation_subdocs[value]))
def create_metadata_subdoc(name, idx, header_value_type, *, value=[], subsampled_annotation=None):
return {
'name': name,
'array_index': idx,
'value': value,
'array_type': header_value_type,
'subsampled_annotation': subsampled_annotation,
'subsamp_threashold': "",
}
I expect the values for each key to do different. Instead all the values are updating at the same time even though I'm accessing specific keys.

How to compare two values in a dictionary and return a third one if the condition is satisfied?

I'm having some trouble in finding a solution to this problem. I need to compare items belonging to different keys in a dictionary. If the comparison equals my parameter, I need a third (new) element to be inserted in a new key on this very same dictionary. Below is an example of what I intend to do. Hope it makes it easier to understand:
A={"names":["jason","peter","mary"],"ages":[25,35,45],"health":["Good","Good","Poor"]}
I need to compare each value of "ages" with each item of "health", respectively. If the value in "ages" is >20 AND the value in "health" is "Good", I need to add values "yes" or "no" to a new key "fit" in this dictionary, according to the results of the comparisons carried out before.
I have been looking for all the possible ways to do this, but it didn't work out.
You can do it in simple way and understand if you are new to python programming. I try to help based on given scenario. #J_H answer is also right.. You can use both answers for your reference.
A={"names":["jason","peter","mary"],"ages":[25,35,45],"health":
["Good","Good","Poor"]}
dicts = {}
age = (A.get("ages"))
health = (A.get("health"))
for i, j in zip(age, health):
if i > 20 and j == "Good":
dicts.setdefault("fit", []).append("yes")
else:
dicts.setdefault("fit", []).append("no")
print(dicts)
Your data is poorly organized; zip can help.
Define a helper predicate:
def is_fit(age, health):
if age > 20 and health == 'Good':
return 'yes'
else:
return 'no'
Reorganize the data:
import pprint
a = {'names': 'jason peter mary'.split(),
'ages': [25, 35, 45],
'health': ['Good', 'Good', 'Poor']}
pprint.pprint(list(zip(a['names'], a['ages'], a['health'])), width=30)
[('jason', 25, 'Good'),
('peter', 35, 'Good'),
('mary', 45, 'Poor')]
Now you're in a position to visit each person's attributes all together:
for name, age, health in zip(a['names'], a['ages'], a['health']):
if is_fit(age, health) == 'yes':
print(name)
a['fit'] = [is_fit(age, health)
for age, health
in zip(a['ages'], a['health'])]

Creating a dictionary of dictionaries from csv file

Hi so I am trying to write a function, classify(csv_file) that creates a default dictionary of dictionaries from a csv file. The first "column" (first item in each row) is the key for each entry in the dictionary and then second "column" (second item in each row) will contain the values.
However, I want to alter the values by calling on two functions (in this order):
trigram_c(string): that creates a default dictionary of trigram counts within the string (which are the values)
normal(tri_counts): that takes the output of trigram_c and normalises the counts (i.e converts the counts for each trigram into a number).
Thus, my final output will be a dictionary of dictionaries:
{value: {trigram1 : normalised_count, trigram2: normalised_count}, value2: {trigram1: normalised_count...}...} and so on
My current code looks like this:
def classify(csv_file):
l_rows = list(csv.reader(open(csv_file)))
classified = dict((l_rows[0], l_rows[1]) for rows in l_rows)
For example, if the csv file was:
Snippet1, "It was a dark stormy day"
Snippet2, "Hello world!"
Snippet3, "How are you?"
The final output would resemble:
{Snippet1: {'It ': 0.5352, 't w': 0.43232}, Snippet2: {'Hel' : 0.438724,...}...} and so on.
(Of course there would be more than just two trigram counts, and the numbers are just random for the purpose of the example).
Any help would be much appreciated!
First of all, please check classify function, because I can't run it. Here corrected version:
import csv
def classify(csv_file):
l_rows = list(csv.reader(open(csv_file)))
classified = dict((row[0], row[1]) for row in l_rows)
return classified
It returns dictionary with key from first column and value is string from second column.
So you should iterate every dictionary entry and pass its value to trigram_c function. I didn't understand how you calculated trigram counts, but for example if you just count the number of trigram appearence in string you could use the function below. If you want make other counting you just need to update code in the for loop.
def trigram_c(string):
trigram_dict = {}
start = 0
end = 3
for i in range(len(string)-2):
# you could implement your logic in this loop
trigram = string[start:end]
if trigram in trigram_dict.keys():
trigram_dict[trigram] += 1
else:
trigram_dict[trigram] = 1
start += 1
end += 1
return trigram_dict

Appending part of a string to a dictionary

say I have a list, items: ['a01:01-24-2011:s1', 'a03:01-24-2011:s2', 'a02:01-24-2011:s2']
which is structured as [animalID:datevisited:stationvisited] for each entry, and wished to count the number of times a station is visited, how would I do so?
There are only two s
tations so if i split it into two count functions thats not a hassle
I've tried
def counts_station:
for item in items:
counts={}
if item[-2] in counts:
counts[item[-2]]=counts[item[-2]]+1
else:
counts[item[-2]]=1
returns counts
as well as
def counts_station:
for item in items:
station=item[-2]
if station in counts:
counts[station]=counts[station]+1
else:
counts[station] = 1
returns counts
help!?
You need to split your string into sub-items before trying to use it as a key, use the range [-2:] instead of just -2, or just take the last character of the string (1 or 2), not the second-to-last. You also had some small errors in your code: needing to initialize counts as an empty dictionary:
items = ['a01:01-24-2011:s1', 'a03:01-24-2011:s2', 'a02:01-24-2011:s2']
def counts_station(items):
counts={}
for item in items:
station=item[-1]
if station in counts:
counts[station]=counts[station]+1
else:
counts[station] = 1
return counts
Another way to do this use .get() with a default value of 0 that is returned if the key doesn't exist:
def counts_station(items):
counts={}
for item in items:
station=item[-1]
counts[station]=counts.get(station,0) + 1
return counts

Resources