I want to make know if there is a command that can do this:
>>>A=dict()
>>>A[1]=3
>>>A
{1:3}
>>>A[1].add(5) #This is the command that I don't know if exists.
>>>A
{1:(3,5)}
I mean, add another value to the same key without quiting the old value added.
It is possible to do this?
You could make the dictionary values into lists:
>>> A = dict()
>>> A[1] = [3]
>>> A
{1: [3]}
>>> A[1].append(5) # Add a new item to the list
>>> A
{1: [3, 5]}
>>>
You may also be interested in dict.setdefault, which has functionality similar to collections.defaultdict but without the need to import:
>>> A = dict()
>>> A.setdefault(1, []).append(3)
>>> A
{1: [3]}
>>> A.setdefault(1, []).append(5)
>>> A
{1: [3, 5]}
>>>
A defaultdict of type list will create an empty list in case you access a key that does not exist in the dictionary so far. This often leads to quite elegant code.
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d[1].append(3)
>>> d[1].append(2)
>>> d
defaultdict(<type 'list'>, {1: [3, 2]})
Using a defaultdict eliminates the "special case" of the initial insert.
from collections import defaultdict
A = defaultdict(list)
for num in (3,5):
A[1].append(num)
Like others pointed out, store the values in a list, but remember to check if the key is in the dictionary to determine whether you need to append or create a new list for that key...
A = dict()
if key in A: A[key].append(value)
else: A[key] = [value]
Related
I'm working on an assignment. Is there anyway a dictionary can have duplicate keys and hold the same or different values. Here is an example of what i'm trying to do:
dict = {
'Key1' : 'Helo', 'World'
'Key1' : 'Helo'
'Key1' : 'Helo', 'World'
}
I tried doing this but when I associate any value to key1, it gets added to the same key1.
Is this possible with a dictionary? If not what other data structure I can use to implement this process?
Use dictionaries of lists to hold multiple values.
One way to have multiple values to a key is to use a dictionary of lists.
x = { 'Key1' : ['Hello', 'World'],
'Key2' : ['Howdy', 'Neighbor'],
'Key3' : ['Hey', 'Dude']
}
To get the list you want (or make a new one), I recommend using setdefault.
my_list = x.setdefault(key, [])
Example:
>>> x = {}
>>> x['abc'] = [1,2,3,4]
>>> x
{'abc': [1, 2, 3, 4]}
>>> x.setdefault('xyz', [])
[]
>>> x.setdefault('abc', [])
[1, 2, 3, 4]
>>> x
{'xyz': [], 'abc': [1, 2, 3, 4]}
Using defaultdict for the same functionality
To make this even easier, the collections module has a defaultdict object that simplifies this. Just pass it a constructor/factory.
from collections import defaultdict
x = defaultdict(list)
x['key1'].append(12)
x['key1'].append(13)
You can also use dictionaries of dictionaries or even dictionaries of sets.
>>> from collections import defaultdict
>>> dd = defaultdict(dict)
>>> dd
defaultdict(<type 'dict'>, {})
>>> dd['x']['a'] = 23
>>> dd
defaultdict(<type 'dict'>, {'x': {'a': 23}})
>>> dd['x']['b'] = 46
>>> dd['y']['a'] = 12
>>> dd
defaultdict(<type 'dict'>, {'y': {'a': 12}, 'x': {'a': 23, 'b': 46}})
I think you want collections.defaultdict:
from collections import defaultdict
d = defaultdict(list)
list_of_values = [['Hello', 'World'], 'Hello', ['Hello', 'World']]
for v in list_of_values:
d['Key1'].append(v)
print d
This will deal with duplicate keys, and instead of overwriting the key, it will append something to that list of values.
Keys are unique to the data. Consider using some other value for a key or consider using a different data structure to hold this data.
for example:
don't use a persons address as a unique key because several people might live there.
a person's social security number or a drivers license is a much better unique id of a person.
you can create your own id to force it to be unique.
I am doing a boolean retrieval project, the first phase is indexing. I am trying to build an inverted index now. Say I got a sorted list like following: how can I merge the items
list = [('a',1),('a',2),('a',3),('b',1),('b',2),('b',3)...]
such that I can get a dictionary like the following and it remains sorted:
dict = {'a':[1,2,3], 'b':[1,2,3]...}, thx a lot
You can do it like this:
>>> import collections
>>> mylist = [('a',1),('a',2),('a',3),('b',1),('b',2),('b',3)]
>>> result = collections.defaultdict(list)
>>> for item in mylist:
result[item[0]].append(item[1])
>>> dict(result)
{'a': [1, 2, 3], 'b': [1, 2, 3]}
defaultdict(list) creates a dictionary in which keys are initialised upon first access to an object created using the callable passed as the argument (in this case list). It avoids having to check whether the key already exists or not.
The last line converts the defaultdict to a normal dict - it is not strictly necessary as defaultdict behaves like a normal dictionary too.
Values are appended to each key in the same order as the original list. However, the keys themselves will not be ordered (this is a property of dictionaries).
Update: if you need the dictionary keys to remain sorted as well, you can do this:
>>> import collections
>>> mylist = [('a',1),('a',2),('c',1),('c',2),('b',1),('b',2)]
>>> result = collections.OrderedDict()
>>> for item in mylist:
if item[0] not in result:
result[item[0]] = list()
result[item[0]].append(item[1])
>>> result
OrderedDict([('a', [1, 2]), ('c', [1, 2]), ('b', [1, 2])])
>>> result.keys()
['a', 'c', 'b']
Obviously, you cannot use dict(result) in this case as dict does not maintain any specific key order.
So I realized that
dict1.update(dict2)
replaces values of dict2 with dict1 if the key exists in both the dictionaries. Is there any way to add the values of dict2 to dict1 directly if the key is present instead of looping around the key,value pairs
You say you want to add the values, but not what type they are. If they are numeric, you may be able to use collections.Counter instead of dict
>>> from collections import Counter
>>> a = Counter({'a':1, 'b':2})
>>> b = Counter({'a':5.4, 'c':6})
>>> a + b
Counter({'a': 6.4, 'c': 6, 'b': 2})
Data frame:
pair = collections.defaultdict(collections.Counter)
e.g.
pair = {'doc1': {'word1':4, 'word2':3},
'doc2': {'word1':2, 'word3':4},
'doc3': {'word2':2, 'word4':1},
...}
I want to keep the data frame but alter the type of this part {'word1':4, 'word2':3} {'word1':2, 'word3':4}``... It is now a Counter and I need a dict.
I tried this to get the data from pair, but I do not know how to create a dict for each doc:
new_pair = collections.defaultdict(collections.Counter)
for doc, tab in testing.form.items():
for word, freq in tab.items():
new_pair[doc][word] = freq
I do not want to change the output. I just need that in each doc, the data type is dict, not Counter.
A Counter is already a dict - or, a subclass of it. But, if you really need exactly a dict for some reason, then its a one-liner:
>>> c = Counter(word1=4, word2=3)
>>> c
Counter({'word1': 4, 'word2': 3})
>>> dict(c)
{'word1': 4, 'word2': 3}
Any Mapping (anything that behaves like a dictionary) can be passed into dict, and you will get a dict with the same contents. There is no need to iterate over it to construct it yourself.
This gives you one loop, with one line in the body instead of a nested loop. But any code of the form:
thing = a new empty collection
for elem in old_thing:
Add something to do with elem to thing
Can usually be done in one line using a generator expression or a list, set or dict comprehension. We're building a dict, so a dict comprehension (the Examples section is what you're most interested in) seems likely. I'll leave coming up with it as an exercise for the reader. ;-)
Since Counter is already a dict.
I would like to suggest this in addition to #lvc answer as well.
>>> c = Counter(word1=4, word2=3)
>>> c
Counter({'word1': 4, 'word2': 3})
>>> isinstance(c,dict)
True
>>> {**c}
{'word1': 4, 'word2': 3}
This allows you to add more key and combine multiple dict or counter
>>> {**c, 'total': sum(c.values())}
{'word1': 4, 'word2': 3, 'total': 7}
Maybe you are looking for:
>>> from collections import defaultdict
>>> pair = defaultdict(dict)
>>> pair[3][2]='hello'
>>>
>>> pair
defaultdict(<type 'dict'>, {3: {2: 'hello'}})
>>>
>>> pair[3]
{2: 'hello'}
>>>
new_pair = {} # simple dict at the top level
for doc, tab in testing.form.items():
for word, freq in tab.items():
# top-level values is word counters
new_pair[doc].setdefault(word, Counter()) += freq
The Counter is also a dict. But depend on you need, maybe the follow code is you want.
new_pair ={}
for doc, tab in pari.items():
new_pair[doc] = {}
for word, freq in tab.items():
new_pair[doc][word] = freq
the new_pair dict is you want. Good Luck!
I have a python dictionary dict1 with more than 20,000 keys and I want to update it with another dictionary dict2. The dictionaries look like this:
dict1
key11=>[value11]
key12=>[value12]
...
...
keyxyz=>[value1x] //common key
...... so on
dict2
key21=>[value21]
key22=>[value22]
...
...
keyxyz=>[value2x] // common key
........ so on
If I use
dict1.update(dict2)
then the keys of dict1 which are similar to keys of dict2 will have their values overwritten by values of dict2. What I want is if a key is already present in dict1 then the value of that key in dict2 should be appended to value of dict1. So
dict1.conditionalUpdate(dict2)
should result in
dict1
key11=>[value11]
key12=>[value12]
key21=>[value21]
key22=>[value22]
...
...
keyxyz=>[value1x,value2x]
A naive method would be iterating over keys of dict2 for each key of dict1 and insert or update keys. Is there a better method? Does python support a built in data structure that supports this kind of functionality?
Use defaultdict from the collections module.
>>> from collections import defaultdict
>>> dict1 = {1:'a',2:'b',3:'c'}
>>> dict2 = {1:'hello', 4:'four', 5:'five'}
>>> my_dict = defaultdict(list)
>>> for k in dict1:
... my_dict[k].append(dict1[k])
...
>>> for k in dict2:
... my_dict[k].append(dict2[k])
...
>>> my_dict[1]
['a', 'hello']
This is actually pretty simple to do using a dict comprehension and itertools.groupby():
dict1 = {1: 1, 2: 2, 3: 3, 4: 4}
dict2 = {5: 6, 7: 8, 1: 1, 2: 2}
from itertools import groupby, chain
from operator import itemgetter
sorted_items = sorted(chain(dict1.items(), dict2.items()))
print({key: [value[1] for value in values] for key, values in groupby(sorted_items, itemgetter(0))})
Gives us:
{1: [1, 1], 2: [2, 2], 3: [3], 4: [4], 5: [6], 7: [8]}
Naturally, this creates a new dict, but if you need to update the first dict, you can do that trivially by updating with the new one. If your values are already lists, this may need some minor modification (but I presume you were doing that for the sake of the operation, in which case, there is no need).
Naturally, if you are using Python 2.x, then you will want to use dict.viewitems() or dict.iteritems() over dict.items(). If you are using a version of Python prior to dict comprehensions, then you could use dict((key , value) for ...) instead.
Another method without importing anything, just with the regular Python dictionary:
>>> dict1 = {1:'a',2:'b',3:'c'}
>>> dict2 = {1:'hello', 4:'four', 5:'five'}
>>> for k in dict2:
... dict1[k] = dict1.get(k,"") + dict2.get(k)
...
>>> dict1
{1: 'ahello', 2: 'b', 3: 'c', 4: 'four', 5: 'five'}
>>>
dict1.get(k,"") returns the value associated to k if it exists or an empty string otherwise, and then append the content of dict2.