Extracting values from common keys in multiple dictionaries - python

So I am currently working on a coding lab where my goal is to try to combine multiple mapping into a single mapping
Eng_Team = [
{'player': 'Harry Kane', 'rating': '90'},
{'player': 'Harry Mcguire', 'rating': '81'},
{'player': 'Phil Foden', 'rating': '84'},
{'player': 'Jack Grealish', 'rating': '85'},
{'player': 'Eric Dier', 'rating': '79'}
]
USA_Team = [
{'player': 'Christian Pulisic', 'rating': '82'},
{'player': 'Gio Reyna', 'rating': '79'},
{'player': 'Weston Mckinnie', 'rating': '78'},
{'player': 'Sergino Dest', 'rating': '79'},
{'player': 'Tyler Adams', 'rating': '79'}
]
I tried
player_lookup = ChainMap(USA_Team,Eng_Team)
print(player_lookup['player'])
to try to get the names of players from both dictionaries. However I am getting this error:
TypeError Traceback (most recent call last)
Input In [49], in <cell line: 5>()
1 from collections import ChainMap
3 player_lookup = ChainMap(USA_Team,Eng_Team)
----> 5 print(player_lookup['player'])
File ~\anaconda3\lib\collections\__init__.py:938, in ChainMap.__getitem__(self, key)
936 for mapping in self.maps:
937 try:
--> 938 return mapping[key] # can't use 'key in mapping' with defaultdict
939 except KeyError:
940 pass
TypeError: list indices must be integers or slices, not str
It is to my knowledge that I might have to create a loop function. How would I do so?

What you are looking for should really be a dict that maps each player's name to its rating, in which case you can chain the two lists of dicts, map the dicts to an itemgetter to produce a sequence of tuples of player name and rating, and then construct a new dict with the sequence:
from operator import itemgetter
from itertools import chain
dict(map(itemgetter('player', 'rating'), chain(Eng_Team, USA_Team)))
This returns:
{'Harry Kane': '90', 'Harry Mcguire': '81', 'Phil Foden': '84', 'Jack Grealish': '85', 'Eric Dier': '79', 'Christian Pulisic': '82', 'Gio Reyna': '79', 'Weston Mckinnie': '78', 'Sergino Dest': '79', 'Tyler Adams': '79'}
Demo: https://replit.com/#blhsing/NotableDeepskyblueDrupal

I think what you're getting stuck on is that you have declared two lists of dictionaries: not two dictionaries. I believe that if you want to combine them into one dictionary you could use something like
player_rating_lookup = {}
for player_dictionary in Eng_Team:
player_rating_lookup[player_dictionary['player']] = player_dictionary['rating']
# adds to the player_rating_lookup dictionary:
# the player name string is the key in this new dictionary, and the rating string is the value.
for player_dictionary in USA_Team:
player_rating_lookup[player_dictionary['player']] = player_dictionary['rating']
# you can just iterate over the two lists of dictionaries separately.

You probably were after something like this:
from collections import ChainMap
# this is not a dictionary, but a list of dictionaries
# so, eng_team['player'] wouldn't actually work
eng_team = [
{'player': 'Harry Kane', 'rating': '90'},
{'player': 'Harry Mcguire', 'rating': '81'},
{'player': 'Phil Foden', 'rating': '84'},
{'player': 'Jack Grealish', 'rating': '85'},
{'player': 'Eric Dier', 'rating': '79'},
{'player': 'John Doe', 'rating': 0}
]
# this is also a list of dictionaries, not a dictionary
usa_team = [
{'player': 'Christian Pulisic', 'rating': '82'},
{'player': 'Gio Reyna', 'rating': '79'},
{'player': 'Weston Mckinnie', 'rating': '78'},
{'player': 'Sergino Dest', 'rating': '79'},
{'player': 'Tyler Adams', 'rating': '79'},
{'player': 'John Doe', 'rating': 1}
]
# so, you'd want to create appropriate dictionaries from the data
# (unless you can just define them as dictionaries right away)
eng_team_dict = {p['player']: {**p} for p in eng_team}
usa_team_dict = {p['player']: {**p} for p in usa_team}
# the dictionaries can be chain-mapped
all_players = ChainMap(eng_team_dict, usa_team_dict)
# this then works
print(all_players['Harry Kane'], all_players['Sergino Dest'])
print(list(all_players.keys()))
# note that duplicate keys will be taken from the first dict in
# the arguments to ChainMap, i.e. `eng_team_dict` in this case
print(all_players['John Doe'])
Output:
{'player': 'Harry Kane', 'rating': '90'} {'player': 'Sergino Dest', 'rating': '79'}
['Christian Pulisic', 'Gio Reyna', 'Weston Mckinnie', 'Sergino Dest', 'Tyler Adams', 'John Doe', 'Harry Kane', 'Harry Mcguire', 'Phil Foden', 'Jack Grealish', 'Eric Dier']
{'player': 'John Doe', 'rating': 0}

Related

Nested Python Object to CSV

I looked up "nested dict" and "nested list" but either method work.
I have a python object with the following structure:
[{
'id': 'productID1', 'name': 'productname A',
'option': {
'size': {
'type': 'list',
'name': 'size',
'choices': [
{'value': 'M'},
]}},
'variant': [{
'id': 'variantID1',
'choices':
{'size': 'M'},
'attributes':
{'currency': 'USD', 'price': 1}}]
}]
what i need to output is a csv file in the following, flattened structure:
id, productname, variantid, size, currency, price
productID1, productname A, variantID1, M, USD, 1
productID1, productname A, variantID2, L, USD, 2
productID2, productname A, variantID3, XL, USD, 3
i tried this solution: Python: Writing Nested Dictionary to CSV
or this one: From Nested Dictionary to CSV File
i got rid of the [] around and within the data and e.g. i used this code snippet from 2 and adapted it to my needs. IRL i can't get rid of the [] because that's simple the format i get when calling the API.
with open('productdata.csv', 'w', newline='', encoding='utf-8') as output:
writer = csv.writer(output, delimiter=';', quotechar = '"', quoting=csv.QUOTE_NONNUMERIC)
for key in sorted(data):
value = data[key]
if len(value) > 0:
writer.writerow([key, value])
else:
for i in value:
writer.writerow([key, i, value])
but the output is like this:
"id";"productID1"
"name";"productname A"
"option";"{'size': {'type': 'list', 'name': 'size', 'choices': {'value': 'M'}}}"
"variant";"{'id': 'variantID1', 'choices': {'size': 'M'}, 'attributes': {'currency': 'USD', 'price': 1}}"
anyone can help me out, please?
thanks in advance
list indices must be integers not strings
The following presents a visual example of a python list:
0 carrot.
1 broccoli.
2 asparagus.
3 cauliflower.
4 corn.
5 cucumber.
6 eggplant.
7 bell pepper
0, 1, 2 are all "indices".
"carrot", "broccoli", etc... are all said to be "values"
Essentially, a python list is a machine which has integer inputs and arbitrary outputs.
Think of a python list as a black-box:
A number, such as 5, goes into the box.
you turn a crank handle attached to the box.
Maybe the string "cucumber" comes out of the box
You got an error: TypeError: list indices must be integers or slices, not str
There are various solutions.
Convert Strings into Integers
Convert the string into an integer.
listy_the_list = ["carrot", "broccoli", "asparagus", "cauliflower"]
string_index = "2"
integer_index = int(string_index)
element = listy_the_list[integer_index]
so yeah.... that works as long as your string-indicies look like numbers (e.g. "456" or "7")
The integer class constructor, int(), is not very smart.
For example, x = int("3 ") will produce an error.
You can try x = int(strying.strip()) to get rid of leading and trailing white-space characters.
Use a Container which Allows Keys to be Strings
Long ago, before before electronic computers existed, there were various types of containers in the world:
cookie jars
muffin tins
carboard boxes
glass jars
steel cans.
back-packs
duffel bags
closets/wardrobes
brief-cases
In computer programming there are also various types of "containers"
You do not have to use a list as your container, if you do not want to.
There are containers where the keys (AKA indices) are allowed to be strings, instead of integers.
In python, the standard container which like a list, but where the keys/indices can be strings, is a dictionary
thisdict = {
"make": "Ford",
"model": "Mustang",
"year": 1964
}
thisdict["brand"] == "Ford"
If you want to index into a container using strings, instead of integers, then use a dict, instead of a list
The following is an example of a python dict which has state names as input and state abreviations as output:
us_state_abbrev = {
'Alabama': 'AL',
'Alaska': 'AK',
'American Samoa': 'AS',
'Arizona': 'AZ',
'Arkansas': 'AR',
'California': 'CA',
'Colorado': 'CO',
'Connecticut': 'CT',
'Delaware': 'DE',
'District of Columbia': 'DC',
'Florida': 'FL',
'Georgia': 'GA',
'Guam': 'GU',
'Hawaii': 'HI',
'Idaho': 'ID',
'Illinois': 'IL',
'Indiana': 'IN',
'Iowa': 'IA',
'Kansas': 'KS',
'Kentucky': 'KY',
'Louisiana': 'LA',
'Maine': 'ME',
'Maryland': 'MD',
'Massachusetts': 'MA',
'Michigan': 'MI',
'Minnesota': 'MN',
'Mississippi': 'MS',
'Missouri': 'MO',
'Montana': 'MT',
'Nebraska': 'NE',
'Nevada': 'NV',
'New Hampshire': 'NH',
'New Jersey': 'NJ',
'New Mexico': 'NM',
'New York': 'NY',
'North Carolina': 'NC',
'North Dakota': 'ND',
'Northern Mariana Islands':'MP',
'Ohio': 'OH',
'Oklahoma': 'OK',
'Oregon': 'OR',
'Pennsylvania': 'PA',
'Puerto Rico': 'PR',
'Rhode Island': 'RI',
'South Carolina': 'SC',
'South Dakota': 'SD',
'Tennessee': 'TN',
'Texas': 'TX',
'Utah': 'UT',
'Vermont': 'VT',
'Virgin Islands': 'VI',
'Virginia': 'VA',
'Washington': 'WA',
'West Virginia': 'WV',
'Wisconsin': 'WI',
'Wyoming': 'WY'
}
i could actually iterate this list and create my own sublist, e.g. e list of variants
data = [{
'id': 'productID1', 'name': 'productname A',
'option': {
'size': {
'type': 'list',
'name': 'size',
'choices': [
{'value': 'M'},
]}},
'variant': [{
'id': 'variantID1',
'choices':
{'size': 'M'},
'attributes':
{'currency': 'USD', 'price': 1}}]
},
{'id': 'productID2', 'name': 'productname B',
'option': {
'size': {
'type': 'list',
'name': 'size',
'choices': [
{'value': 'XL', 'salue':'XXL'},
]}},
'variant': [{
'id': 'variantID2',
'choices':
{'size': 'XL', 'size2':'XXL'},
'attributes':
{'currency': 'USD', 'price': 2}}]
}
]
new_list = {}
for item in data:
new_list.update(id=item['id'])
new_list.update (name=item['name'])
for variant in item['variant']:
new_list.update (varid=variant['id'])
for vchoice in variant['choices']:
new_list.update (vsize=variant['choices'][vchoice])
for attribute in variant['attributes']:
new_list.update (vprice=variant['attributes'][attribute])
for option in item['option']['size']['choices']:
new_list.update (osize=option['value'])
print (new_list)
but the output is always the last item of the iteration, because i always overwrite new_list with update().
{'id': 'productID2', 'name': 'productname B', 'varid': 'variantID2', 'vsize': 'XXL', 'vprice': 2, 'osize': 'XL'}
here's the final solution which worked for me:
data = [{
'id': 'productID1', 'name': 'productname A',
'variant': [{
'id': 'variantID1',
'choices':
{'size': 'M'},
'attributes':
{'currency': 'USD', 'price': 1}},
{'id':'variantID2',
'choices':
{'size': 'L'},
'attributes':
{'currency':'USD', 'price':2}}
]
},
{
'id': 'productID2', 'name': 'productname B',
'variant': [{
'id': 'variantID3',
'choices':
{'size': 'XL'},
'attributes':
{'currency': 'USD', 'price': 3}},
{'id':'variantID4',
'choices':
{'size': 'XXL'},
'attributes':
{'currency':'USD', 'price':4}}
]
}
]
for item in data:
for variant in item['variant']:
dic = {}
dic.update (ProductID=item['id'])
dic.update (Name=item['name'].title())
dic.update (ID=variant['id'])
dic.update (size=variant['choices']['size'])
dic.update (Price=variant['attributes']['price'])
products.append(dic)
keys = products[0].keys()
with open('productdata.csv', 'w', newline='', encoding='utf-8') as output_file:
dict_writer = csv.DictWriter(output_file, keys,delimiter=';', quotechar = '"', quoting=csv.QUOTE_NONNUMERIC)
dict_writer.writeheader()
dict_writer.writerows(products)
with the following output:
"ProductID";"Name";"ID";"size";"Price"
"productID1";"Productname A";"variantID1";"M";1
"productID1";"Productname A";"variantID2";"L";2
"productID2";"Productname B";"variantID3";"XL";3
"productID2";"Productname B";"variantID4";"XXL";4
which is exactly what i wanted.

From MongoDB convert from dictionary to row with Pandas

This is a test coming from MongoDB, I need to convert to MySQL. But! Sometimes there is more then one "agents", if that's the case I need each agent on their own row and that agent should have the same "display_name". For example Walter should have Gloria on one row and Barb on next and both have Walt Mosley under "display_name".
[{'name': 'Loomis, Gloria',
'primaryemail': 'gloria#gmail.com',
'primaryphone': '212-382-1121'},
{'name': 'Hogson, Barb',
'primaryemail': 'bho124#aol.com',
'primaryphone': ''}]
I've tried this but it just splits out the key/values.
a,b,c = [[d[e] for d in test] for e in sorted(test[0].keys())]
print(a,b,c)
This is the original JSON format:
{'_id': ObjectId('58e6ececafb08d6'),
'item_type': 'Contributor',
'role': 0,
'short_bio': 'Walter Mosley (b. 1952)',
'firebrand_id': 1588,
'display_name': 'Walter Mosley',
'first_name': 'Walter',
'last_name': 'Mosley',
'slug': 'walter-mosley',
'updated': datetime.datetime(2020, 1, 7, 8, 17, 11, 926000),
'image': 'https://s3.amazonaws.com/8588-book-contributor.jpg',
'social_media_name': '',
'social_media_link': '',
'website': '',
'agents': [{'name': 'Loomis, Gloria',
'primaryemail': 'gloria#gmail.com',
'primaryphone': '212-382-1121'},
{'name': 'Hogson, Barb',
'primaryemail': 'bho124#aol.com',
'primaryphone': ''}],
'estates': [],
'deleted': False}
If you've an array of dictionaries from your JSON file, try this :
JSON input :
inputJSON = [{'item_type': 'Contributor',
'role': 0,
'short_bio': 'Walter Mosley (b. 1952)',
'firebrand_id': 1588,
'display_name': 'Walter Mosley',
'first_name': 'Walter',
'last_name': 'Mosley',
'slug': 'walter-mosley',
'image': 'https://s3.amazonaws.com/8588-book-contributor.jpg',
'social_media_name': '',
'social_media_link': '',
'website': '',
'agents': [{'name': 'Loomis, Gloria',
'primaryemail': 'gloria#gmail.com',
'primaryphone': '212-382-1121'},
{'name': 'Hogson, Barb',
'primaryemail': 'bho124#aol.com',
'primaryphone': ''}],
'estates': [],
'deleted': False}]
Code :
import copy
finalJSON = []
for each in inputJSON:
for agnt in each.get('agents'):
newObj = copy.deepcopy(each)
newObj['agents'] = agnt
finalJSON.append(newObj)
print(finalJSON)

How to combine dictionaries that have the same element inside a list?

I have a list of dictionaries. Some dictionaries share the same elements.
data = [
{'New_PCP_Name': 'Jack0',
'Member_Name': 'Jack0, 0',
'Member_ID': '111',
'DOB': '111',
'PCP_ID':'111'
},
{'New_PCP_Name': 'Jack0',
'Member_Name': 'Jack00, 00',
'Member_ID': '222',
'DOB': '222',
'PCP_ID':'111'
},
{'New_PCP_Name': 'Jack1',
'Member_Name': 'Jack1, 1',
'Member_ID': '333',
'DOB': '333',
'PCP_ID':'333'
},
{'New_PCP_Name': 'Jack2',
'Member_Name': 'Jack2, 2',
'Member_ID': '444',
'DOB': '444',
'PCP_ID':'444'
}
]
I need to combine them in a specific format. The first 2 dicts share the same element 'New_PCP_Name': 'Jack0'. So I want to combine them. The final product is as below. This format has to be exactly like this because I need to use this format in a mail merge from the data imported from Excel.
data = [
{'New_PCP_Name': 'Jack0',
'PCP_ID':'111',
'Member_Name':[{'Member_Name':'Jack0, 0','Member_ID':'111','DOB':'111'},
{'Member_Name': 'Jack00, 00', 'Member_ID': '222', 'DOB': '222'}]
},
{'New_PCP_Name': 'Jack1',
'Member_Name': 'Jack1, 1',
'Member_ID': '333',
'DOB': '333',
'PCP_ID':'333'
},
{'New_PCP_Name': 'Jack2',
'Member_Name': 'Jack2, 2',
'Member_ID': '444',
'DOB': '444',
'PCP_ID':'444'
}
]
I'm new in python.I have tried breaking up the list, modifying the dictionaries and putting them back together as below. That didn't work out. Please help me figure out how to reformat the list of dicts. Or is there a way to import data from Excel in that specific format for the rows that share the same cell values?
data2=[]
for x in range (0,len(data),1):
print(x)
print(data[x])
a = data[x]
print(a['New_PCP_Name'])
if x+1<=len(data):
if data[x]['New_PCP_Name'] == data[x+1]['New_PCP_Name']:
print('yes')
data2.append(data[x])
else:
print('no')
print('data2=', data2)
One possibility is using itertools.groupby (doc):
data = [
{'New_PCP_Name': 'Jack0',
'Member_Name': 'Jack0, 0',
'Member_ID': '111',
'DOB': '111',
'PCP_ID':'111'
},
{'New_PCP_Name': 'Jack0',
'Member_Name': 'Jack00, 00',
'Member_ID': '222',
'DOB': '222',
'PCP_ID':'111'
},
{'New_PCP_Name': 'Jack1',
'Member_Name': 'Jack1, 1',
'Member_ID': '333',
'DOB': '333',
'PCP_ID':'333'
},
{'New_PCP_Name': 'Jack2',
'Member_Name': 'Jack2, 2',
'Member_ID': '444',
'DOB': '444',
'PCP_ID':'444'
}
]
from itertools import groupby
out = []
for v, g in groupby(sorted(data, key=lambda k: k['New_PCP_Name']), lambda k: (k['New_PCP_Name'], k['PCP_ID'])):
l = [*g]
if len(l) == 1:
out.append(l[0])
else:
pcp_id = None
for i in l:
del i['New_PCP_Name']
del i['PCP_ID']
out.append({'New_PCP_Name': v[0],
'PCP_ID': v[1],
'Member_Name':l
})
from pprint import pprint
pprint(out)
Prints:
[{'Member_Name': [{'DOB': '111', 'Member_ID': '111', 'Member_Name': 'Jack0, 0'},
{'DOB': '222',
'Member_ID': '222',
'Member_Name': 'Jack00, 00'}],
'New_PCP_Name': 'Jack0',
'PCP_ID': '111'},
{'DOB': '333',
'Member_ID': '333',
'Member_Name': 'Jack1, 1',
'New_PCP_Name': 'Jack1',
'PCP_ID': '333'},
{'DOB': '444',
'Member_ID': '444',
'Member_Name': 'Jack2, 2',
'New_PCP_Name': 'Jack2',
'PCP_ID': '444'}]
Try
new_data_dic = {}
for e in data:
new_name = e['New_PCP_Name']
if new_name not in new_data_dic:
new_data_dic[new_name] = e.copy()
else:
if type(new_data_dic[new_name]['Member_Name'] == str):
inner = new_data_dic[new_name].copy()
del inner['New_PCP_Name']
del new_data_dic[new_name]['Member_ID']
del new_data_dic[new_name]['DOB']
new_data_dic[new_name]['Member_Name'] = [inner]
inner = e.copy()
del inner['New_PCP_Name']
new_data_dic[new_name]['Member_Name'].append(inner)
data2 = list(new_data_dic.values())
Explained: The 'New_PCP_Name' is a key, so I create a dictionary. I transform 'Member_Name' to a list in case I see another occurence of the same key. On subsequent appearances I can append.

Python: Extra comma on csv.Dictreader column

I have this read function where it reads a csv file using csv.DictReader. The file.csv is separated by commas and it fully reads. However, this part of my file has a column that contains multiple commas. My question is, how can I make sure that comma is counted as part of a column? I cannot alter my csv file to meet the criteria.
Text File:
ID,Name,University,Street,ZipCode,Country
12,Jon Snow,U of Winterfell,Winterfell #45,60434,Westeros
13,Steve Rogers,NYU,108, Chelsea St.,23333,United States
20,Peter Parker,Yale,34, Tribeca,32444,United States
34,Tyrion Lannister,U of Casterly Rock,Kings Landing #89, 43543,Westeros
The desired output is this:
{'ID': '12', 'Name': 'Jon Snow', 'University': 'U of Winterfell', 'Street': 'Winterfell #45', 'ZipCode': '60434', 'Country': 'Westeros'}
{'ID': '13', 'Name': 'Steve Rogers', 'University': 'NYU', 'Street': '108, Chelsea St.', 'ZipCode': '23333', 'Country': 'United States'}
{'ID': '20', 'Name': 'Peter Parker', 'University': 'Yale', 'Street': '34, Tribeca', 'ZipCode': '32444', 'Country': 'United States'}
{'ID': '34', 'Name': 'Tyrion Lannister', 'University': 'U of Casterly Rock', 'Street': 'Kings Landing #89', 'ZipCode': '43543', 'Country': 'Westeros'}
As you can tell the 'Street' has at least two commas due to the numbers:
13,Steve Rogers,NYU,108, Chelsea St.,23333,United States
20,Peter Parker,Yale,34, Tribeca,32444,United States
Note: Most of the columns being read splits by a str,str BUT under the 'Street' column it is followed by a str, str (there is an extra space after the comma). I hope this makes sense.
The options I tried looking out is using re.split, but I don't know how to implement it on my read file. I was thinking re.split(r'(?!\s),(?!\s)',x[:-1])? How can I make sure the format from my file will count as part of any column? I can't use pandas.
My current output looks like this right now:
{'ID': '12', 'Name': 'Jon Snow', 'University': 'U of Winterfell', 'Street': 'Winterfell #45', 'ZipCode': '60434', 'Country': 'Westeros'}
{'ID': '13', 'Name': 'Steve Rogers', 'University': 'NYU', 'Street': '108', 'ZipCode': 'Chelsea St.', 'Country': '23333', None: ['United States']}
{'ID': '20', 'Name': 'Peter Parker', 'University': 'Yale', 'Street': '34', 'ZipCode': 'Tribeca', 'Country': '32444', None: ['United States']}
{'ID': '34', 'Name': 'Tyrion Lannister', 'University': 'U of Casterly Rock', 'Street': 'Kings Landing #89', 'ZipCode': '43543', 'Country': 'Westeros'}
This is my read function:
import csv
list = []
with open('file.csv', mode='r') as csv_file:
csv_reader = csv.DictReader(csv_file, delimiter=",", skipinitialspace=True)
for col in csv_reader:
list.append(dict(col))
print(dict(col))
You can't use csv if the file isn't valid CSV format.
You need to call re.split() on ordinary lines, not on dictionaries.
list = []
with open('file.csv', mode='r') as csv_file:
keys = csv_file.readline().strip().split(',') # Read header line
for line in csv_file:
line = line.strip()
row = re.split(r'(?!\s),(?!\s)',line)
list.append(dict(zip(keys, row)))
The actual solution for the problem is modifying the script that generates the csv file.
If you have a chance to modify that output you can do 2 things
Use a delimiter other than a comma such as | symbol or ; whatever you believe it doesn't exist in the string.
Or enclose all columns with " so you'll be able to split them by , which are actual separators.
If you don't have a chance to modify the output.
And if you are sure about that multiple commas are only in the street column; then you should use csv.reader instead of DictReader this way you can get the columns by Indexes that you are already sure. for instance row[0] will be ID row[1] will be Name and row[-1] will be Country row[-2] will be ZipCode so row[2:-2] would give you what you need i guess. Indexes can be arranged but the idea is clear I guess.
Hope that helps.
Edit:
import csv
list = []
with open('file.csv', mode='r') as csv_file:
csv_reader = csv.reader(csv_file, delimiter=",", skipinitialspace=True)
# pass the header row
next(csv_reader)
for row in csv_reader:
list.append({"ID": row[0],
"Name": row[1],
"University": row[2],
"Street": ' '.join(row[3:-2]),
"Zipcode": row[-2],
"Country": row[-1]})
print(list)
--
Here is the output (with pprint)
[{'Country': 'Westeros',
'ID': '12',
'Name': 'Jon Snow',
'Street': 'Winterfell #45',
'University': 'U of Winterfell',
'Zipcode': '60434'},
{'Country': 'United States',
'ID': '13',
'Name': 'Steve Rogers',
'Street': '108 Chelsea St.',
'University': 'NYU',
'Zipcode': '23333'},
{'Country': 'United States',
'ID': '20',
'Name': 'Peter Parker',
'Street': '34 Tribeca',
'University': 'Yale',
'Zipcode': '32444'},
{'Country': 'Westeros',
'ID': '34',
'Name': 'Tyrion Lannister',
'Street': 'Kings Landing #89',
'University': 'U of Casterly Rock',
'Zipcode': '43543'}]
-- second edit
edited the index on the street.
Regards.

Matching keys in different lists of dicts

I have a csv.DictReader instance of dicts and a list of dicts.
instance:
{'Salary': '3000', 'Name': 'James Jones', 'GameInfo': 'Den#Cle 07:30PM ET',
'AvgPointsPerGame': '4.883', 'teamAbbrev': 'Cle', 'Position': 'SG'}
{'Salary': '3000', 'Name': 'Justin Anderson', 'GameInfo': 'Orl#Dal 09:00PM ET',
'AvgPointsPerGame': '13.161', 'teamAbbrev': 'Dal', 'Position': 'SF'}
list:
[
{'playername': 'Justin Anderson', 'points': '6.94'},
{'playername': 'DeAndre Liggins', 'points': '11.4'},
]
I cannot figure out how to iterate over these lists of dictionaries, match the Name and playername keys, then spit the ['Name'] from one dict and the ['points'] from the matching dict. In the example above I would match Justin Anderson from the two sets of dicts then print out Justin Anderson, 6.94
The core of the app takes 2 CSV's and makes them lists of dicts.
It's not really efficient this way but it wouldn't require any preprocessing:
# Instead of your CSVReader:
dicts = [{'Salary': '3000', 'Name': 'James Jones', 'GameInfo': 'Den#Cle 07:30PM ET', 'AvgPointsPerGame': '4.883', 'teamAbbrev': 'Cle', 'Position': 'SG'},
{'Salary': '3000', 'Name': 'Justin Anderson', 'GameInfo': 'Orl#Dal 09:00PM ET', 'AvgPointsPerGame': '13.161', 'teamAbbrev': 'Dal', 'Position': 'SF'}]
list_of_dicts = [
{'playername': 'Justin Anderson', 'points': '6.94'},
{'playername': 'DeAndre Liggins', 'points': '11.4'},
]
# For each dictionary in the CSVReader
for dct in dicts:
# For each dictionary in your list of dictionaries
for subdict in list_of_dicts:
# Check if the name and playername matches
if dct['Name'] == subdict['playername']:
# I just print out the results, you need to do your logic here
print(dct['Name'])
print(dct)
print('matching')
print(subdict)
and this prints:
Justin Anderson
{'Salary': '3000', 'Name': 'Justin Anderson', 'GameInfo': 'Orl#Dal 09:00PM ET', 'AvgPointsPerGame': '13.161', 'Position': 'SF', 'teamAbbrev': 'Dal'}
matching
{'playername': 'Justin Anderson', 'points': '6.94'}
If you want it faster than you should preprocess your list of dictionaries so that you can simply lookup the playername:
>>> dict_of_dicts = {dct['playername']: dct for dct in list_of_dicts}
>>> dict_of_dicts
{'DeAndre Liggins': {'playername': 'DeAndre Liggins', 'points': '11.4'},
'Justin Anderson': {'playername': 'Justin Anderson', 'points': '6.94'}}
Then the loop simplifies to:
for dct in dicts:
if dct['Name'] in dict_of_dicts:
print(dct['Name'])
print(dct)
print('matching')
print(dict_of_dicts[dct['Name']])
giving the same result.

Categories

Resources