Insertion order and Duplicate Keys in Dictionary - python

I'm using python 3.7.
I have a dictionary something like this.
dict = { 'a' :2 , 'a' :1 , 'b':3 , 'c':4}
print(dict)
O/P ={'a' : 1 , 'b' :2 , 'c':3 }
Now In python 3.7 dictionary must maintain insertion order .So expected o/p will be {'a':2 , 'b':3 , 'c' :4} , but ('a',2) is being removed from dictionary instead of('a',1) .Why is this happening ??Is there any rule for removing duplicate keys in python ??

From the Python documentation:
The main operations on a dictionary are storing a value with some key and extracting the value given the key. It is also possible to delete a key:value pair with del. If you store using a key that is already in use, the old value associated with that key is forgotten. It is an error to extract a value using a non-existent key.
See: https://docs.python.org/3/tutorial/datastructures.html

Maintaining insertion order is concerned with different keys:
>>> dct = {'a': 1, 'b': 2} # do NOT shadow built-in name 'dict'
>>> print(dct)
{'a': 1, 'b': 2}
# and not
{'b': 2, 'a': 1} # which was totally possible before Python3.6
When receiving multiple values for the same key, the last one provided wins:
>>> dct = {'a': 3, 'a': 1, 'b': 2}
>>> print(dct)
{'a': 1, 'b': 2}
This is similar to the following scenario:
>>> dct = {}
>>> dct['a'] = 3
>>> dct['a'] = 1
>>> dct['b'] = 2
Would you expect dct['a'] to be 3 now because of the "insertion order"? Certainly not!

The value assigned to a key can be anything and even duplicated since it merely a value. Keys however, are similar to a variable name. Like in many programming languages, if a variable name is used again in the same scope or method, the first variable and its value is overwritten by the second since it is more recent.
In this case it may be more appropriate to to assign a different key (think of keys as identifiers) to the same value if that is your wish. Like this
dict = { 2: 'a', 1: 'a', 3:'b', 4:'c'}
print(dict)
O/P = {1: 'a', 2: 'a', 3: 'b', 4: 'c'}

Related

Is there a way to store values in one dictionary key that has multiple optional values?

I want to do something like this:
my_dict = {
('a'|'b'|'c') : 1
}
Clearly, this doesn't work but I was wondering if there are ways around it that are the same or more efficient than writing each out:
my_dict = {
'a' : 1,
'b' : 1,
'c' : 1
}
Any ideas?
You can create a dictionary with multiple keys all mapping to the same value using dict.fromkeys.
The first argument is a sequence of keys; the second argument is the value.
>>> dict.fromkeys('abc', 1)
{'a': 1, 'b': 1, 'c': 1}
'abc' works as a sequence of keys because in this case all your keys are strings of one character. More generally you can use a tuple or a list:
>>> dict.fromkeys(['a','b','c'], 1)
{'a': 1, 'b': 1, 'c': 1}
(N.B. creating a dict this way might cause problems if your value was mutable, since all the keys would reference the same value object.)
Create a dictionary with 3 keys, all with the value 1:
x = ('a', 'b', 'c')
y = 1
thisdict = dict.fromkeys(x, y)
print(thisdict)

Duplicate dictionary keys in initialization - Python

Is it correct to say that the rightmost/last key-value pair for a given key would always be considered if there are multiple identical keys when initializing a dictionary ?
Example :
Dict = {'A': 5, 'B': 6, 'A': 10}
Will Dict['A'] always be 10 in all python implementations? Where does python enforce this ?
You know that python dict can't contain duplicate keys. So
Dict = {'A': 5, 'B': 6)
Dict.update({'A': 10})
print(Dict['A'])
will result in the last value assigned to the key A:
Output:
10
So the situation is almost like that, python goes through the dictionary during evaluation, and keeps the last value assigned to the keys.
I know dict aren't ordered, but:
That doesn't mean python will jump back and forth on the dict when parsing the dict into memory.
It will parse through it from left to right to get the collect the data, but it stores the dict without keeping its order.
Python dict can not have duplicate keys. if you try to add the same key again, it will update the existing key with the new value.
Dict = {'A': 5, 'B': 6, 'A': 10}
print(Dict)
{'A': 10, 'B': 6}
the above statement execution is similar to below:
Dict['A'] = 5
print(Dict)
{'A'=5}
Dict['B'] = 6
print(Dict)
{'A'=5, 'B'=6}
Dict['A'] = 10
print(Dict)
{'A'=10, 'B'=6}

Python : Get list by index not key in defaultdict

I'm new to python and I have become stuck on a data type issue.
I have a script which looks a bit like this
dd = defaultdict(list)
for i in arr:
dd[color].append(i)
which creates a default dict which resembles something along the lines of
dd = [('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
However I need to now access the first list([2,4]). I have tried
print(dd[0])
but this game me the following output
[][][]
I know the defaultdict has data in it as I have printed it in its entirety. However other than access the first item by its dictionary index I don't know how to access it. However, other than access the list by the dictionary key I don't know how to get it. However, I don't know the name of the key until I populate the dict.
I have thought about creating a list of lists rather than a defaultdict but being able to search via key is going to be really usefull for another part of the code so I would like to maintain this data structure if possible.
is there a way to grab the list by an index number or can you only do it using a key?
You can get a list of keys, pick the key by index, then access that key.
print(dd[dd.keys()[0]])
Note that a dictionary in Python is an unordered collection. This means that the order of keys is undefined. Consider the following example:
from collections import defaultdict
d = defaultdict (int)
d['a'] = 1
d['b'] = 2
d['c'] = 3
d['d'] = 4
d['e'] = 5
print (d)
My Python2 gives:
defaultdict(<type 'int'>, {'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4})
Python3 output is different by the way:
defaultdict(<class 'int'>, {'c': 3, 'b': 2, 'a': 1, 'e': 5, 'd': 4})
So, you will have to use some other means to remember the order in which you populate the dictionary. Either maintain a separate list of keys (colors) in the order you need, or use OrderedDict.

Not getting the same result when inverting a dictionary twice

I'm trying to invert a simple dictionary like:
{'a' : 1, 'b' : 2, 'c' : 3, 'd' : 4}
I'm using this function:
def invert(d):
return dict([(x,y) for y,x in d.iteritems()])
Now when I invert my dictionary, everything works out fine. When I invert it twice however, I get:
{'a': 1, 'c': 3, 'b': 2, 'd': 4}
which is not in the same order as the dictionary I started with. Is there a problem with my invert function? Sorry I'm kinda new to python, but thanks for any help!
That is correct, dictionaries are unordered in python
from another so answer answer:
CPython implementation detail: Keys and values are listed in an
arbitrary order which is non-random, varies across Python
implementations, and depends on the dictionary’s history of insertions
and deletions.
from the docs:
It is best to think of a dictionary as an unordered set of key: value
pairs, with the requirement that the keys are unique (within one
dictionary). A pair of braces creates an empty dictionary: {}. Placing
a comma-separated list of key:value pairs within the braces adds
initial key:value pairs to the dictionary; this is also the way
dictionaries are written on output.
Python dictionaries are unsorted by design.
You can use collections.OrderedDict instead if you really need this behaviour.
Try running this code:
d = {
'a' : 1, 'b' : 2,
'c' : 3, 'd' : 4
}
def invert(d):
return dict([(x,y) for y,x in d.iteritems()])
print d
d = invert(d)
print d
d = invert(d)
print d
This is the output:
{'a': 1, 'c': 3, 'b': 2, 'd': 4}
{1: 'a', 2: 'b', 3: 'c', 4: 'd'}
{'a': 1, 'c': 3, 'b': 2, 'd': 4}
As you can see, it technically is the same dictionary, but when you declare it, it is unordered.

Setting a value to a dictionary's dictionary value

The code:
>>> mydict = {}
>>> keylist = ['a','b','c']
>>> mydict=dict.fromkeys(keylist,{})
>>> mydict['a']['sample'] = 1
>>> mydict
{'a': {'sample': 1}, 'c': {'sample': 1}, 'b': {'sample': 1}}
I was expecting mydict['a']['sample'] = 1 would set the value just for a's dictionary value and would get this: {'a': {'sample': 1}, 'c': {}, 'b': {}}.
What am I missing here? What should I have to do to get the expected output?
The problem is that you added the same dictionary to mydict for every key. You want to add different dictionaries, like so:
mydict = dict((key, {}) for key in keylist)
In the above code, you create a new dictionary to pair with each key. In your original code, the function fromkeys took the argument (the empty dictionary you provided) and added that exact argument - that single empty dictionary you created to pass in to the function - to each of the keys. When that one dictionary was changed, then, that change showed up everywhere.

Categories

Resources