Iterating over a list of dictionaries - python

JSON
Newbie here. I want to iterate over this list of dictionaries to get the "SUPPLIER" for every dictionary. I tried
turbine_json_path = '_maps/turbine/turbine_payload.json'
with open(turbine_json_path, "r") as f:
turbine = json.load(f)
# print((turbine))
for supplier in turbine[0]['GENERAL']:
print(supplier["SUPPLIER"])
But I get a type error.. TypeError: string indices must be integers
Any help is appreciated.

for d in turbine:
print(d["GENERAL"]["SUPPLIER"])

There is only one supplier key in your dictionary, so it would be
supplier = turbine[0]['GENERAL']['SUPPLIER']
Other wise your for loop is looping over the keys within the 'GENERAL' dictionary, which are strings.

Related

Change list according to dictionary items

Hello I have a list that looks like:
>>>ids
'70723295',
'75198124',
'140',
'199200',
'583561',
'71496270',
'69838760',
'70545907',
...]
I also have a dictionary that gives those numbers a 'name'. Now I want to create a new list that contains only the names, in the order like the numbers before.. so replace the numbers in the right order with the right names from the dictionary.
I tried:
with open('/home/anja/Schreibtisch/Master/ABA/alltogether/filelist.txt') as f:
ids = [line.strip() for line in f.read().split('\n')]
rev_subs = { v:k for v,k in dictionary.items()}
new_list=[rev_subs.get(item,item) for item in ids]
#dict looks like:
'16411': 'Itgax',
'241041': 'Gm4956',
'22419': 'Wnt5b',
'20174': 'Ruvbl2',
'71833': 'Dcaf7',
...}
But new_list is still the same as ids.
What am I doing wrong?
Maybe the dictionary keys are not in the format you think? Maybe the dictionary contains integers, meanwhile the ids are strings. I would investigate on that, it seems a mismatch of types more than an empty (or non-matching) dictionary.
Your dictionary keys are bs4.element.NavigableString objects rather than strings, so you cannot use strings as keys to look up its values.
You can fix this by converting the keys to strings when you build rev_subs:
rev_subs = {str(k): v for k, v in dictionary.items()}

Take 2 key values from list of python dicts & make new list/tuple/array/dictionary with each index containing 2 key values from 1st listed dict

I have a list of dictionaries in a json file.
I have iterated through the list and each dictionary to obtain two specific key:value pairs from each dictionary for each element.
i.e. List[dictionary{i(key_x:value_x, key_y:value_y)}]
My question is now:
How do I place these two new key: value pairs in a new list/dictionary/array/tuple, representing the two key: value pairs extracted for each listed element in the original?
To be clear:
ORIGINAL_LIST (i.e. with each element being a nested dictionary) =
[{"a":{"blah":"blah",
"key_1":value_a1,
"key_2":value_a2,
"key_3":value_a3,
"key_4":value_a4,
"key_5":value_a5,},
"b":"something_a"},
{"a":{"blah":"blah",
"key_1":value_b1,
"key_2":value_b2,
"key_3":value_b3,
"key_4":value_b4,
"key_5":value_b5,},
"b":"something_b"}]
So my code so far is:
import json
from collections import *
from pprint import pprint
json_file = "/some/path/to/json/file"
with open(json_file) as json_data:
data = json.load(json_data)
json_data.close()
for i in data:
event = dict(i)
event_key_b = event.get('b')
event_key_2 = event.get('key_2')
print(event_key_b)#print value of "b" for each nested dict for 'i'
print(event_key_2)#print value of "key_2" for each nested dict for 'i'
To be clear:
FINAL_LIST(i.e. with each element being a nested dictionary) =
[{"b":"something_a", "key_2":value_2},
{"b":"something_b", "key_2":value_2}]
So I have an answer to getting the keys into individual dictionaries, as follows in the code below. The only problem is that the value for 'key_2' in the original json dictionaries is either an int value or it is "" for values which are 0. My script just returns 'None' for all instances of value_2 for key_2. How can I get it to read the appropriate values for 'value_2'? I want to only return dictionaries for cases where 'value_2' > 0 (i.e. where value_2 != "")
Below is the current code:
import json
from pprint import pprint
json_file = "/some/path/to/json/file"
with open(json_file) as json_data:
data = json.load(json_data)
json_data.close()
for i in data:
event_key_b = event.get('b')
for x in i:
event_key_2 = event.get('key_2')
x = {'b' : something_b, 'key_2' : value_2}
print(x)
Also, if there are any more elegant solutions anyone can think of I would really be interested in learning them ... Some of the json files I'm looking at can range from 200 dictionary entries in the original list to 2,000,000. I'm planning to feed my parsed results into a message queue for processing by a different service and any efficiencies in the code will help for scalability in processing. Also if anyone has any recommendations to give on Redis vs. RabbitMQ, I'd really appreciate it

Creating a nested dictionary where inner values are lists

So I want to create a nested dictionary of lists where the inner value is a list that allows duplicates:
d = {'45678':{'ant':['N4', 'N4', 'P3', 'P3']}}
This is what I have so far but can't figure out how to append a list to the inner value:
d={}
with open(file_path, 'r') as f:
for l in f.readlines()[4:]:
peaks = l.split()
if '1' in peaks[5]:
d.setdefault(peaks[0], {})['ant'] = [peaks[7]]
Which returns:
{'20065037': {'ant': ['N4']}}
My question is how can I append a list as the inner value in the nested dictionary?
I think I may have figured out what you're trying to do.
Does this help?
d.setdefault(peaks[0], {}).setdefault('ant', []).append(peaks[7])
If not, please explain what the file looks like or something else about what you're trying to do.
Assuming your code is basically sound (in terms of processing the file), you should use setdefault on the inner dictionary and append to the list.
d={}
with open(file_path, 'r') as f:
for l in f.readlines()[4:]:
peaks = l.split()
if '1' in peaks[5]:
d.setdefault(peaks[0], {}).setdefault('ant', []).append(peaks[7])
Currently, you are always creating a new list using [peaks[7]] instead of giving an option to append.

Nested dictionary behavior

I am trying to learn how to manipulate data in python.
I have the following data in a txt file
{"summonerId":000000,"games":[{"gameId":111111,"invalid":false,"gameMode":"CLASSIC","gameType":"MATCHED_GAME","subType":"NORMAL","mapId":11,"teamId":200,"championId":89,"spell1":3,"spell2":4,"level":30,"ipEarned":237,"createDate":1443314494341,"fellowPlayers":[{"summonerId":46350758,"teamId":100,"championId":157}],"stats":{"level":15,"goldEarned":10173,"numDeaths":5,"minionsKilled":48,"championsKilled":1,"goldSpent":9205,"totalDamageDealt":48752,"totalDamageTaken":23464,"team":200,"win":true,"largestMultiKill":1,"physicalDamageDealtPlayer":9064,"magicDamageDealtPlayer":35714,"physicalDamageTaken":18944,"magicDamageTaken":4005,"timePlayed":1831,"totalHeal":4129,"totalUnitsHealed":5,"assists":24,"item0":3401,"item1":2049,"item2":3117,"item3":3068,"item4":3075,"item5":1028,"item6":3340,"magicDamageDealtToChampions":9062,"physicalDamageDealtToChampions":3348,"totalDamageDealtToChampions":12411,"trueDamageDealtPlayer":3974,"trueDamageTaken":514,"wardKilled":1,"wardPlaced":16,"totalTimeCrowdControlDealt":104,"playerRole":2,"playerPosition":4}]}
My end goal is to be able to display a specific piece of information from the "stats" dictionary.
When I run the following code
import json
matches = open('testdata.txt', 'r')
output = matches.read()
data=json.loads(output)
display = data["games"]
print("Info: " + str(display))
The output is everything that corresponds to the "games" key as I would expect.
When I try
import json
matches = open('testdata.txt', 'r')
output = matches.read()
data=json.loads(output)
display = data["games"]["stats"]
print("Info: " + str(display))
I receive: TypeError: list indices must be integers, not str
I'm not really sure how to proceed given that the key is clearly a string and not an integer...
Your data["games"] value is a list; each element in that list is a dictionary, and it is those dictionaries in the list that (may) have the 'stats' key. A list can contain 0 or more elements; in this specific case there is just 1 but there could be more or none.
Loop over the list of dictionaries, or pick a specific dictionary from the list with indexing. Since there is only one in your specific example, you could just index that 1 element with the 0 index:
display = data["games"][0]["stats"]

python csv TypeError: unhashable type: 'list'

Hi Im trying to compare two csv files and get the difference. However i get the above mentioned error. Could someone kindly give a helping hand. Thanks
import csv
f = open('ted.csv','r')
psv_f = csv.reader(f)
attendees1 = []
for row in psv_f:
attendees1.append(row)
f.close
f = open('ted2.csv','r')
psv_f = csv.reader(f)
attendees2 = []
for row in psv_f:
attendees2.append(row)
f.close
attendees11 = set(attendees1)
attendees12 = set(attendees2)
print (attendees12.difference(attendees11))
When you iterate csv reader you get lists, so when you do
for row in psv_f:
attendees2.append(row)
Row is actually a list instance. so attendees1 / attendees2 is a list of lists.
When you convert it to set() it need to make sure no item appear more than once, and set() relay on hash function of the items in the list. so you are getting error because when you convert to set() it try to hash a list but list is not hashable.
You will get the same exception if you do something like this:
set([1, 2, [1,2] ])
More in sets: https://docs.python.org/2/library/sets.html
Happened on the line
attendees11 = set(attendees1)
didn't it? You are trying to make a set from a list of lists but it is impossible because set may only contain hashable types, which list is not. You can convert the lists to tuples.
attendees1.append(tuple(row))
Causes you created list of list:
attendees1.append(row)
Like wise:
attendees2.append(row)
Then when you do :
attendees11 = set(attendees1)
The error will be thrown
What you should do is :
attendees2.append(tuple(row))

Categories