Update dictionary if in list - python

I'm running through an excel file reading line by line to create dictionaries and append them to a list, so I have a list like:
myList = []
and a dictionary in this format:
dictionary = {'name': 'John', 'code': 'code1', 'date': [123,456]}
so I do this: myList.append(dictionary), so far so good. Now I'll go into the next line where I have a pretty similar dictionary:
dictionary_two = {'name': 'John', 'code': 'code1', 'date': [789]}
I'd like to check if I already have a dictionary with 'name' = 'John' in myList so I check it with this function:
def checkGuy(dude_name):
return any(d['name'] == dude_name for d in myList)
Currently I'm writing this function to add the guys to the list:
def addGuy(row_info):
if not checkGuy(row_info[1]):
myList.append({'name':row_info[1],'code':row_info[0],'date':[row_info[2]]})
else:
#HELP HERE
in this else I'd like to dict.update(updated_dict) but I don't know how to get the dictionary here.
Could someone help so dictionary appends the values of dictionary_two?

I would modify checkGuy to something like:
def findGuy(dude_name):
for d in myList:
if d['name'] == dude_name:
return d
else:
return None # or use pass
And then do:
def addGuy(row_info):
guy = findGuy(row_info[1])
if guy is None:
myList.append({'name':row_info[1],'code':row_info[0],'date':[row_info[2]]})
else:
guy.update(updated_dict)

This answer suggestion is pasted on the comments where it was suggested that if "name" is the only criteria to search on then it could be used as a key in a dictionary instead of using a list.
master = {"John" : {'code': 'code1', 'date': [123,456]}}
def addGuy(row_info):
key = row_info[1]
code = row_info[0]
date = row_info[2]
if master.get(key):
master.get(key).update({"code": code, "date": date})
else:
master[key] = {"code": code, "date": date}

If you dict.update the existing data each time you see a repeated name, your code can be reduced to a dict of dicts right where you read the file. Calling update on existing dicts with the same keys is going to overwrite the values leaving you with the last occurrence so even if you had multiple "John" dicts they would all contain the exact same data by the end.
def read_file():
results = {name: {"code": code, "date": date}
for code, name, date in how_you_read_into_rows}
If you actually think that the values get appended somehow, you are wrong. If you wanted to do that you would need a very different approach. If you actually want to gather the dates and codes per user then use a defauldict appending the code,date pair to a list with the name as the key:
from collections import defaultdict
d = defaultdict(list)
def read_file():
for code, name, date in how_you_read_into_rows:
d["name"].append([code, date])
Or some variation depending on what you want the final output to look like.

Related

Trying to nest a dictionary from a previous dictionary

so I have the following scenario:
dictionary=[
{category1:clothes, category2:cheap, category3:10},
{category1:clothes, category2:normal, category3:20}]
I need a dictionary that goes {clothes:{cheap:10, normal:20}}
All I have figured out is something that prints them individually
for i in range(len(dictionary)):
print({dictionary[i]['category1']:{dictionary[i][category2],dictionary[i][category3]}}
But it prints them individually, and I can't figure out how to nest them together since this just gives me two dictionaries with the format I want, but the nested dictionary just has either the values from the first list or the second. I have also tried
[{item['category1']: {'Attribute': attr_key, 'Value': item[attr_key]}}
for item in dictionary for attr_key in item if attr_key != 'category1']
It is the same, it gives more lines whereas I just need one dictionary with cat1 and the other ones nested in its dictionary.
raw = {}
for item in dictionary:
value1 = item.get('category2')
value2 = item.get('category3')
raw.update({value1:value2})
data = {}
data[dictionary[0].get('category1')] = raw
Output:
{'clothes': {'cheap': 10, 'normal': 20}}
This should do it.
import collections
dictionary=[
{'category1':'clothes', 'category2':'cheap', 'category3':10},
{'category1':'clothes', 'category2':'normal', 'category3':20}
]
newdict = collections.defaultdict(dict)
for item in dictionary:
newdict[item['category1']].update({item['category2']: item['category3']})
print(newdict)

Add values to an existing dictionary key in Python

I need to append dictionary values to an already existing JSON file. How can I be able to do that?
My details.json File
{"name": "someName"}
Dictionary generated by my python script
list1 = {"name": "someOthername"}
with open("details.json") as r:
data = json.load(r)
desirableDict = data.append(list1) # It has to be something like this
print(desirableDict)
Desirable Output: {"name": ["someName", "someOthername"]}
You can check all keys within a for loop and put the values ​​of the json file and list1 inside a list like this:
import json
list1 = {"name": "someOthername"}
with open("details.json") as file:
data = json.load(file)
desirableDict = data.copy()
for key in data:
if key in list1:
if type(data[key]) is list:
data[key].append(list1[key])
else:
desirableDict[key] = [data[key],list1[key]]
print(desirableDict)
It seems like you need deep merging of structures. I would like to recommend you to use this awesome library https://pypi.org/project/deepmerge/.
There are a lot of examples like you want to achieve.
from deepmerge import always_merger
base = {"foo": ["bar"]}
next = {"foo": ["baz"]}
expected_result = {'foo': ['bar', 'baz']}
result = always_merger.merge(base, next)
assert expected_result == result

how to write multiple line statement to single line python dictionary

I want to write this below code in one line. I have lots of data. so the page goes on. So i want to shrink it. How to make it possible. I know it is possible in python. Help me with some solutions.
data['url']=url
data['user agent']=userAgent
data['browser']=browser
data['uniqueId']=uniqueId
data['ip']=ip
data['language']=language
and its going on.
I tried this but it fails.
data['url','user agent','browser'...] = url,useragent,browser....
keys = ("url", "ip", "language")
values = ("http://example.com", "93.184.216.34", "en")
# if you want to update an existing dict:
data = {}
data.update(zip(keys, values))
# if you just want to create a dict:
data = dict(zip(keys, values))
If you want to set all the values at once, you could do something like this:
data = { 'url': url, 'user agent': userAgent, ... }
If data already has... data, you could update it with:
data.update({ 'url': url, 'user agent': userAgent, ... })
You can use dict comprehension:
keys = ['url','user agent','browser']
vals = [url,useragent,browser]
data = {key:val for key,val in zip(keys,vals)}
You could do a for loop:
Example:
for key, value in Data:
finalData[key] = value

Removing a key from a nested dictionary based on value

I previusly asked about adding, and someone helped me out with append. My new problem is trying to delete a key with a nested list, e.g.:
JSON:
data = {"result":[{"name":"Teddy","list":{"0":"24","1":"43","2":"56"}},
{"name":"Barney","list":{"0":"24","1":"43","2":"56"}]}
Python:
name = input("Input a key to delete") #Must hold a value.
data["result"].pop(name)
E.g. Barney => then delete Barney etc.
I use the method below to find a key, but I am not sure this is the correct approach.
Finding Barney:
for key in data['result']:
if key['name'] == name:
print("Found!!!!")
I am not sure. This surely does not work, maybe I should loop through each key or? Any suggestion or code example is worth.
After Delete: Now that barney was deleted the dictionary remains like this.
data = {"result":[{"name":"Teddy","list":{"0":"24","1":"43","2":"56"}}]}
If the goal is to remove list items from the JSON document, you'll want to:
Convert the JSON document into a Python data structure
Manipulate the Python data structure
Convert the Python data structure back to a JSON document
Here is one such program:
import json
def delete_keys(json_string, name):
data = json.loads(json_string)
data['result'][:] = [d for d in data['result'] if d.get('name') != name]
json_string = json.dumps(data)
return json_string
j = '''
{"result":[{"name":"Teddy",
"list":{"0":"24","1":"43","2":"56"}},
{"name":"Barney","list":{"0":"24","1":"43","2":"56"}}]}'''
print delete_keys(j, 'Barney')
Result:
$ python x.py
{"result": [{"list": {"1": "43", "0": "24", "2": "56"}, "name": "Teddy"}]}
Note this list comprehension:
data['result'][:] = [d for d in data['result'] if d.get('name') != name]
The form l[:] = [item in l if ...] is one way to delete several items from a list according to the indicated condition.
Since data['result'] is a list, you'll have to go to the index and delete the key. If you're looking to delete the key across all indices in the list, you could quickly write a function that iterates through the list and deletes the matching key
def delete_key(list_obj, key):
for value in list_obj:
if key in value:
value.pop(key)
return list_obj
result = delete_key(data["result"], 'key1')
You can convert the JSON into a JavaScript object.
var resultString = '{'result':[{'key1':'value1','key2':'value2'}, {'key1':'value3','key2':'value4'}]}';
var result = JSON.parse(resultString);
Once you do, you should be more aware that this is an array of objects. You need to know which index you want to remove. You can use the .find method for arrays
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
if you don't know the index.
var inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
function findCherries(fruit) {
return fruit.name === 'cherries';
}
console.log(inventory.find(findCherries));
// { name: 'cherries', quantity: 5 }
Realize though that find does not work in IE. Once you know the index, you can split the array.
var myFish = ["angel", "clown", "drum", "mandarin", "surgeon"];
var removed = myFish.splice(3, 1);
// removed is ["mandarin"]
// myFish is ["angel", "clown", "drum", "surgeon"]
from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

removing json items from array if value is duplicate python

I am incredibly new to python.
I have an array full of json objects. Some of the json objects contain duplicated values. The array looks like this:
[{"id":"1","name":"Paul","age":"21"},
{"id":"2","name":"Peter","age":"22"},
{"id":"3","name":"Paul","age":"23"}]
What I am trying to do is to remove an item if the name is the same as another json object, and leave the first one in the array.
So in this case I should be left with
[{"id":"1"."name":"Paul","age":"21"},
{"id":"2","name":"Peter","age":"22"}]
The code I currently have can be seen below and is largely based on this answer:
import json
ds = json.loads('python.json') #this file contains the json
unique_stuff = { each['name'] : each for each in ds }.values()
all_ids = [ each['name'] for each in ds ]
unique_stuff = [ ds[ all_ids.index(text) ] for text in set(texts) ]
print unique_stuff
I am not even sure that this line is working ds = json.loads('python.json') #this file contains the json as when I try and print ds nothing shows up in the console.
You might have overdone in your approach. I might tend to rewrite the list as a dictionary with "name" as a key and then fetch the values
ds = [{"id":"1","name":"Paul","age":"21"},
{"id":"2","name":"Peter","age":"22"},
{"id":"3","name":"Paul","age":"23"}]
{elem["name"]:elem for elem in ds}.values()
Out[2]:
[{'age': '23', 'id': '3', 'name': 'Paul'},
{'age': '22', 'id': '2', 'name': 'Peter'}]
Off-course the items within the dictionary and the list may not be ordered, but I do not see much of a concern. If it is, let us know and we can think over it.
If you need to keep the first instance of "Paul" in your data a dictionary comprehension gives you the opposite result.
A simple solution could be as following
new = []
seen = set()
for record in old:
name = record['name']
if name not in seen:
seen.add(name)
new.append(record)
del seen
First of all, your json snippet has invalid format - there are dot instead of commas separating some keys.
You can solve your problem using a dictionary with names as keys:
import json
with open('python.json') as fp:
ds = json.load(fp) #this file contains the json
mem = {}
for record in ds:
name = record["name"]
if name not in mem:
mem[name] = record
print mem.values()

Categories

Resources