I have an embedded dictionary created as:
all_stats = {}
all_stats['user1'] = {}
I first add an entry with:
all_stats['stat0'] = 1
I then have a dictionary of each additional entries that will be added to all_stats for that user:
user_stats = {'stat1':5, 'stat2':3}
How can I add these to the embedded dictionary, so I end up with:
print(all_stats)
{'user1': {'stat0:1', 'stat1':5, 'stat2':3}}
I've tried:
all_stats['user1'].update(k=v for k,v in user_stats.items())
but this throws a SyntaxError
You don't need the for loop; you can update one dictionary with another dictionary directly:
all_stats['user1']['stat0'] = 1
all_stats['user1'].update(user_stats)
all_stats
# {'user1': {'stat0': 1, 'stat1': 5, 'stat2': 3}}
As for the Syntax Error, as commented by #idjaw, you can't use k=v in a comprehension in the way you've used; Something similar but acceptable would be:
all_stats['user1'].update({k:v for k,v in user_stats.items()})
Related
So I have a dictionary
dict={'Andrew':5, 'Brian':3, 'Clive':2, 'David':4}
it contains the names of volunteers and the number of times that they have volunteered for a particular duty. The dictionary is regularly updated by providing both the dictionary and a list to a function upd.
For the current update the following list has been declared - each name represents a new volunteer session:
ulist = ['Brian', 'David', 'Peter']
Write and demonstrate the function upd. Any ideas where to start
I have
def upd(lst):
I know its not much, but I am just learning about lists and dictionaries.
TIA
David.
EDIT:
My apologies, I should have been more specific
the upd function should create the dictionary and append/increment when a user is found, if not, it should create new user
Here is what I imagine your requirements are:
If a name in ulist is already in the dictionary, increment the value associated with it, otherwise create an entry for the name and initialize the value to 1.
This code is quite simple really. Just iterate through each name in ulist and check to see if it is in my_dictionary, if not then add it, if so then increment it.
my_dictionary = {'Andrew':5, 'Brian':3, 'Clive':2, 'David':4}
ulist = ['Brian', 'David', 'Peter']
def udp(lst):
for name in lst:
if name in my_dictionary:
my_dictionary[name] += 1
else:
my_dictionary[name] = 1
udp(ulist)
print(my_dictionary)
Results:
{'Andrew': 5, 'Brian': 4, 'Clive': 2, 'David': 5, 'Peter': 1}
Note: You named your dictionary dict which is technically a keyword in Python so I recommend changing it to something like my_dictionary as shown in my example.
#Input
dict_1 = {"conn": {"ts":15,"uid":"ABC","orig_h":"10.10.210.250"}}
dict_2 = {"conn": {"ts":15,"uid":"ABC","orig_h":"10.10.210.252"}}
#Mapper can be modified as required
mapper = {"10.10.210.250":"black","192.168.2.1":"black"}
I am getting each dict in a loop, in each iteration I need to check a dict against the mapper and append a flag based on match between dict_1.orig_h and mapper.10.10.210.250 . I have the flexibility to define the mapper however I need.
So the desired result would be:
dict_1 = {"conn": {"ts":15,"uid":"ABC","orig_h":"10.10.210.250", "class":"black"}}
dict_2 will remain unchanged since there is no matching value in mapper.
This is kinda what I want, but it works only if orig_h is an int
import collections
result = collections.defaultdict(dict)
for d in dict_1:
result[d[int('orig_h')]].update(d)
for d in mapper:
result[d[int('orig_h')]].update(d)
Not much explaining to be done; if the ip is in the mapper dictionary (if mapper has a key which is that ip) then set the desired attribute of the dict to the value of the key in the mapper dict ('black' here).
def update_dict(dic, mapper):
ip = dic['conn']['orig_h']
if ip in mapper:
dic['conn']['class'] = mapper[ip]
which works exactly as desired:
>>> update_dict(dict_1, mapper)
>>> dict_1
{'conn': {'ts': 15, 'uid': 'ABC', 'orig_h': '10.10.210.250', 'class': 'black'}}
>>> update_dict(dict_2, mapper)
>>> dict_2
{'conn': {'ts': 15, 'uid': 'ABC', 'orig_h': '10.10.210.252'}}
Extracting the conn value for simplicity:
conn_data = dict_1['conn']
conn_data['class'] = mapper[conn_data['orig_h']]
A two liner, extracting class and dict if the 'orig_h' is in the mapper dictionary's keys, if it id, keep it, otherwise don't keep it, then create a new dictionary comprehension inside the list comprehension to add 'class' to the dictionary's 'conn' key's dictionary.
l=[(i,mapper[i['conn']['orig_h']]) for i in (dict_1,dict_2) if i['conn']['orig_h'] in mapper]
print([{'conn':dict(a['conn'],**{'class':b})} for a,b in l])
BTW this answer chooses the dictionaries automatically
I have the following dictionary (It is for creating json),
temp = {'logs':[]}
I want to append dictionaries, but i only got 1 key:val at a time.
what I tried:
temp['logs'].append({key:val})
This does as expected and appends the dict to the array.
But now I want to add a key/val pair to this dictionary, how can I do this?
I've tried using append/extend but that just adds a new dictionary to the list.
But now I want to add a key/val pair to this dictionary
You can index the list and update that dictionary:
temp['logs'][0].update({'new_key': 'new_value'})
You can use this command to change your dict values :
>>> temp['logs'][0]={'no':'val'}
>>> temp
{'logs': [{'no': 'val'}]}
And this one to add values :
>>> temp['logs'][0].update({'yes':'val'})
>>> temp
{'logs': [{'key': 'val', 'yes': 'val'}]}
There must be unique "key" every time you append it. (If it is for json)
Also making "=" will update your old dictionary
What I have done when I was stuck once is
user = {}
name,password,id1 = [],[],[]
user1=session.query(User).all()
for i in user1:
name=i.name
password=i.password
id1=i.id
user.update({ id1:{
"name" : name,
"password" : password,
}
})
check this link might be helpful to you
How to convert List of JSON frames to JSON frame
Note that adding a dictionary (or any object) to a list only stores a reference, not a copy.
You can therefor do this:
>>> temp = {'logs': []}
>>> log_entry = {'key1': 'val1'}
>>> temp['logs'].append(log_entry)
>>> temp
{'logs': [{'key1': 'val1'}]}
>>> log_entry['key2'] = 'val2'
>>> temp
{'logs': [{'key2': 'val2', 'key1': 'val1'}]}
However, you might be able to circumvent to whole issue by using dict comprehension (only in Python >=2.7)
>>> temp = {'logs': [{key: value for key, value in my_generator}]
Try this example:
temp = {
'logs':[]
}
[temp['logs'].append(log) for log in errors['logs']]
Your log data would be list with multiple dictionary
I was wondering if there was a way to initialize a dictionary in python with keys but no corresponding values until I set them. Such as:
Definition = {'apple': , 'ball': }
and then later i can set them:
Definition[key] = something
I only want to initialize keys but I don't know the corresponding values until I have to set them later. Basically I know what keys I want to add the values as they are found. Thanks.
Use the fromkeys function to initialize a dictionary with any default value. In your case, you will initialize with None since you don't have a default value in mind.
empty_dict = dict.fromkeys(['apple','ball'])
this will initialize empty_dict as:
empty_dict = {'apple': None, 'ball': None}
As an alternative, if you wanted to initialize the dictionary with some default value other than None, you can do:
default_value = 'xyz'
nonempty_dict = dict.fromkeys(['apple','ball'],default_value)
You could initialize them to None.
you could use a defaultdict. It will let you set dictionary values without worrying if the key already exists. If you access a key that has not been initialized yet it will return a value you specify (in the below example it will return None)
from collections import defaultdict
your_dict = defaultdict(lambda : None)
It would be good to know what your purpose is, why you want to initialize the keys in the first place. I am not sure you need to do that at all.
1) If you want to count the number of occurrences of keys, you can just do:
Definition = {}
# ...
Definition[key] = Definition.get(key, 0) + 1
2) If you want to get None (or some other value) later for keys that you did not encounter, again you can just use the get() method:
Definition.get(key) # returns None if key not stored
Definition.get(key, default_other_than_none)
3) For all other purposes, you can just use a list of the expected keys, and check if the keys found later match those.
For example, if you only want to store values for those keys:
expected_keys = ['apple', 'banana']
# ...
if key_found in expected_keys:
Definition[key_found] = value
Or if you want to make sure all expected keys were found:
assert(all(key in Definition for key in expected_keys))
You can initialize the values as empty strings and fill them in later as they are found.
dictionary = {'one':'','two':''}
dictionary['one']=1
dictionary['two']=2
Comprehension could be also convenient in this case:
# from a list
keys = ["k1", "k2"]
d = {k:None for k in keys}
# or from another dict
d1 = {"k1" : 1, "k2" : 2}
d2 = {k:None for k in d1.keys()}
d2
# {'k1': None, 'k2': None}
q = input("Apple")
w = input("Ball")
Definition = {'apple': q, 'ball': w}
Based on the clarifying comment by #user2989027, I think a good solution is the following:
definition = ['apple', 'ball']
data = {'orange':1, 'pear':2, 'apple':3, 'ball':4}
my_data = {}
for k in definition:
try:
my_data[k]=data[k]
except KeyError:
pass
print my_data
I tried not to do anything fancy here. I setup my data and an empty dictionary. I then loop through a list of strings that represent potential keys in my data dictionary. I copy each value from data to my_data, but consider the case where data may not have the key that I want.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to raise error if duplicates keys in dictionary
I was recently generating huge dictionaries with hundreds of thousands of keys (such that noticing a bug by looking at them wasn't feasible). They were syntactically correct, yet there was a bug somewhere. It boiled down to "duplicate keys":
{'a':1, ..., 'a':2}
this code compiles fine and I could not figure out why a key has value of 2 as I expected 1. The problem is obvious now.
The question is how I can prevent that in the future. I think this is impossible within python. I used
grep "'.*'[ ]*:" myfile.py | sort | uniq -c | grep -v 1
which is not bulletproof. Any other ideas (within python, this grep is just to illustrate what I'd tried)?
EDIT: I don't want duplicate keys, just need to spot that this occurs and edit data manually
A dict cannot contain double keys. So all you need to do is execute the code and then dump the repr() of the dict.
Another option is creating the dict items as (key, value) tuples. By storing them in a list you can easily create a dict from them and then check if the len()s of the dict/list differ.
If you need to have multiple values per key you can store the values in a list using defaultdict.
>>> from collections import defaultdict
>>> data_dict = defaultdict(list)
>>> data_dict['key'].append('value')
>>> data_dict
defaultdict(<type 'list'>, {'key': ['value']})
>>> data_dict['key'].append('second_value')
>>> data_dict
defaultdict(<type 'list'>, {'key': ['value', 'second_value']})
Are you generating a Python file containing a giant dictionary? Something like:
print "{"
for lines in file:
key, _, value = lines.partition(" ")
print " '%s': '%s',"
print "}"
If so, there's not much you can do to prevent this, as you cannot easily override the construction of the builtin dict.
Instead I'd suggest you validate the data while constructing the dictionary string. You could also generate different syntax:
dict(a = '1', a = '2')
..which will generate a SyntaxError if the key is duplicated. However, these are not exactly equivalent, as dictionary keys are a lot more flexible than keyword-args (e.g {123: '...'} is valid, butdict(123 = '...')` is an error)
You could generate a function call like:
uniq_dict([('a', '...'), ('a', '...')])
Then include the function definition:
def uniq_dict(values):
thedict = {}
for k, v in values:
if k in thedict:
raise ValueError("Duplicate key %s" % k)
thedict[k] = v
return thedict
You don't say or show exactly how you're generating the dictionary display you have where the duplicate keys are appearing. But that is where the problem lies.
Instead of using something like {'a':1, ..., 'a':2} to construct the dictionary, I suggest that you use this form: dict([['a', 1], ..., ['a', 2]]) which will create one from a supplied list of [key, value] pairs. This approach will allow you to check the list of pairs for duplicates before passing it to dict() to do the actual construction of the dictionary.
Here's an example of one way to check the list of pairs for duplicates:
sample = [['a', 1], ['b', 2], ['c', 3], ['a', 2]]
def validate(pairs):
# check for duplicate key names and raise an exception if any are found
dups = []
seen = set()
for key_name,val in pairs:
if key_name in seen:
dups.append(key_name)
else:
seen.add(key_name)
if dups:
raise ValueError('Duplicate key names encountered: %r' % sorted(dups))
else:
return pairs
my_dict = dict(validate(sample))