Python: Value of Dictionary as List - Initiate - python

I want to create a dictionary where the value is a list. Now with every new incoming key I want to start a new list.
If I simply try to append to the dictionary key value it shows an error, since the value is not yet declared a list, and I can't do this at the beginning since I don't know how many keys I'll have.
For example (Note that for MyDict keyList is variable, something not previously known)
keyList = [['a',1,2],['b',3,4]]
MyDict={}
for key in keyList:
MyDict[key[0]].append(key[1:])
What I want to create is:
MyDict={'a': [[1, 2]], 'b': [[3, 4]]}
Is there a way to do this?

You can use setdefault.
Instead of MyDict[key[0]].append(key[1:])
Try using MyDict.setdefault(key[0],[]).append(key[1:])
So when you are trying to append value, if the list doesn't exist it will make a default list and then append value to it

What you need is defaultdict, which is supplied with Python exactly for this purpose:
keyList = [['a',1,2],['b',3,4]]
MyDict=defaultdict(list)
for key in keyList:
MyDict[key[0]].append(key[1:])
print(MyDict)
Output
defaultdict(<class 'list'>, {'b': [[3, 4]], 'a': [[1, 2]]})
defaultdict gets in its constructor a function which is called without arguments to create default elements. list without arguments creates an empty list.
defaultdict behaves in all other ways like a normal dictionary.
If, nevertheless, in the end you want a simple dict, then convert it using dict:
print(dict(MyDict))
gives
{'b': [[3, 4]], 'a': [[1, 2]]}

Use collections.defaultdict. Example:
from collections import defaultdict
d = defaultdict(lambda: [])
d['key'].append('value to be add in list')
Sidenote: Defaultdict takes a callable argument, which means that you can also create your dict in this way:
defaultdict(list)

Related

python : how to order lists of dictionary values alphabetically, keeping to order of the dictionary the same, not sorting the dict by value

Is there an easy way to reorder a list of values in a dictionary alphabetically while keeping the order of the keys the same? I'm not looking to sort the dictionary by values just alphabetically order the lists of them. Thanks
Assuming you just didn't care about the old data ordering, you could just run this function:
def alphabetizeDictValues(dictionary):
for key in dictionary:
dictionary[key].sort()
The sort function of a list sorts the list in-place (making it lossy), so this would only work if you didn't care about the old ordering. This means that the memory requirement is lower, but also means you don't have a reference to how your list was previously sorted. Alternatively, if you wanted to save the old ordering, you could create this function
def alphabetizeDictValues(dictionary):
dupeDictionary = {}
for key in dictionary:
oldLst = list(dictionary[key])
dupeDictionary[key] = oldLst
dictionary[key].sort()
return dupeDictionary
This would return a copy of the input dictionary (with lists not sorted) while the dictionary you passed in would be the sorted version.
Assuming you want to sort the values independently of the keys (which can change the key: value association), you can create a new dictionary:
d = {'b': 1, 'c': 0, 'a': 2}
d2 = dict(zip(d, sorted(d.values())))
Output: {'b': 0, 'c': 1, 'a': 2}
Maybe I'm overthinking this and you just want:
sorted(d.values())
# [0, 1, 2]

Can't crate a dictionary from two lists using dictionary comprehension with two FORs. Why?

I know that there are a bunch of ways to make a dictionary out of two lists, but I wanted to do it using two FOR loops to iterate over both lists. Therefore, I used the following code. Surprisingly, the code doesn't iterate over the second list that contains the values of the dictionary keys and only considers the last element of the list as the value.
key = ['hello', 'mello', 'vello']
value = [1, 2, 3]
dictionary = {k: v for k in key for v in value}
print('dictionary is ', dictionary)
the result was:
dictionary is: {'hello': 3, 'mello': 3, 'vello': 3}
But I expect that the result would be:
dictionary is: {'hello': 1, 'mello': 2, 'vello': 3}
I appreciate it if anyone can clarify this for me.
My understanding is the full dictionary is being recreated each loop with each number as the key, resulting in only your final output being that of the last value (best shown by reversing your key and value statements, returning {1: 'vello', 2: 'vello', 3: 'vello', 4: 'vello'}
If the other is your intended output, this should work fine:
dictionary = dict(zip(key,value))
You can use zip for this purpose.
dictionary = dict(zip(keys, values))

How to Update values (List forms) from while loop in dictionary python

I don't really understand the concept of python dictionary, can anyone help me? I want the program to have similar functionality as append in list python
d = {'key': ['value']}
print(d)
# {'key': ['value']}
d['key'] = ['mynewvalue']
print(d)
# {'key': ['mynewvalue']}
what I want the output of the program, either :
print(d)
#{'key': ['value'],'key': ['mynewvalue']}
or :
print(d)
#{'key': ['value','mynewvalue']}
Sure: first thing first, you can't have two identical keys in a dictionary. So:
{'key': 'myfirstvalue', 'key': 'mysecondvalue'}
wouldn't work. If a key has multiple values, then the key's value should be a list of values, like in your last option. Like in a real dictionary, you won't find, word: definition, word: another definition but word: a list of definitions.
In this regard, you could kind of think of a dictionary as a collection of variables - you can't assign two values to a variable except by assigning a list of values to variable.
x = 4
x = 5
is working code, but the first line is rendered meaningless. x is only equal to 5, not both 4 and 5. You could, however, say:
x = [4, 5]
I often use dictionaries for trees of data. For example, I'm working on a project involving counties for every state in the US. I have a dictionary with a key for each state, and the value of each key is another dictionary, with a key for each county, and the value for each of those dictionaries is another dictionary with the various data points for that county.
That said, you can interact with your dictionary just like you would with variables.
mylist = [1, 2, 3, 4]
mylist.append(5)
print(mylist)
will print:
[1,2,3,4,5]
But also:
mydict = {'mylist': [1,2,3,4]}
mydict['mylist'].append(5)
does the same thing.
mydict['mylist']
is the same as
mylist
in the first example. Both are equal to the list [1,2,3,4]
You cannot have same keys multiple times in a dict in python. The first output scenario you gave is invalid. The value of a dict can contain any data and in your case, it can be accessed and modified just as a list. You can modify the code as given below to get the output as desired in scenario number 2.
d = {'key': ['value']}
print(d)
# {'key': ['value']}
d['key'].append('mynewvalue')
print(d)
#{'key': ['value','mynewvalue']}
you can try it:
d = {'key': ['value']}
d['key'].append("mynewvalue")
print(d)
Output will be: {'key': ['value', 'mynewvalue']}
For the first implementation you want, I think you are violating the entire idea of dictionary, we can not have multiple keys with the same name.
For the second implementation you could write a function like this:
def updateDict(mydict,value):
mydict['key'].append(value)

In Python how to obtain a partial view of a dict?

Is it possible to get a partial view of a dict in Python analogous of pandas df.tail()/df.head(). Say you have a very long dict, and you just want to check some of the elements (the beginning, the end, etc) of the dict. Something like:
dict.head(3) # To see the first 3 elements of the dictionary.
{[1,2], [2, 3], [3, 4]}
Thanks
Kinda strange desire, but you can get that by using this
from itertools import islice
# Python 2.x
dict(islice(mydict.iteritems(), 0, 2))
# Python 3.x
dict(islice(mydict.items(), 0, 2))
or for short dictionaries
# Python 2.x
dict(mydict.items()[0:2])
# Python 3.x
dict(list(mydict.items())[0:2])
Edit:
in Python 3.x:
Without using libraries it's possible to do it this way. Use method:
.items()
which returns a list of dictionary keys with values.
It's necessary to convert it to a list otherwise an error will occur 'my_dict' object is not subscriptable. Then convert it to the dictionary. Now it's ready to slice with square brackets.
dict(list(my_dict.items())[:3])
import itertools
def glance(d):
return dict(itertools.islice(d.iteritems(), 3))
>>> x = {1:2, 3:4, 5:6, 7:8, 9:10, 11:12}
>>> glance(x)
{1: 2, 3: 4, 5: 6}
However:
>>> x['a'] = 2
>>> glance(x)
{1: 2, 3: 4, u'a': 2}
Notice that inserting a new element changed what the "first" three elements were in an unpredictable way. This is what people mean when they tell you dicts aren't ordered. You can get three elements if you want, but you can't know which three they'll be.
I know this question is 3 years old but here a pythonic version (maybe simpler than the above methods) for Python 3.*:
[print(v) for i, v in enumerate(my_dict.items()) if i < n]
It will print the first n elements of the dictionary my_dict
one-up-ing #Neb's solution with Python 3 dict comprehension:
{k: v for i, (k, v) in enumerate(my_dict.items()) if i < n}
It returns a dict rather than printouts
For those who would rather solve this problem with pandas dataframes. Just stuff your dictionary mydict into a dataframe, rotate it, and get the first few rows:
pd.DataFrame(mydict, index=[0]).T.head()
0 hi0
1 hi1
2 hi2
3 hi3
4 hi4
From the documentation:
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.
I've only toyed around at best with other Python implementations (eg PyPy, IronPython, etc), so I don't know for certain if this is the case in all Python implementations, but the general idea of a dict/hashmap/hash/etc is that the keys are unordered.
That being said, you can use an OrderedDict from the collections library. OrderedDicts remember the order of the keys as you entered them.
If keys are someway sortable, you can do this:
head = dict([(key, myDict[key]) for key in sorted(myDict.keys())[:3]])
Or perhaps:
head = dict(sorted(mydict.items(), key=lambda: x:x[0])[:3])
Where x[0] is the key of each key/value pair.
list(reverse_word_index.items())[:10]
Change the number from 10 to however many items of the dictionary reverse_word_index you want to preview
A quick and short solution can be this:
import pandas as pd
d = {"a": [1,2], "b": [2, 3], "c": [3, 4]}
pd.Series(d).head()
a [1, 2]
b [2, 3]
c [3, 4]
dtype: object
This gives back a dictionary:
dict(list(my_dictname.items())[0:n])
If you just want to have a glance of your dict, then just do:
list(freqs.items())[0:n]
Order of items in a dictionary is preserved in Python 3.7+, so this question makes sense.
To get a dictionary with only 10 items from the start you can use pandas:
d = {"a": [1,2], "b": [2, 3], "c": [3, 4]}
import pandas as pd
result = pd.Series(d).head(10).to_dict()
print(result)
This will produce a new dictionary.
d = {"a": 1,"b": 2,"c": 3}
for i in list(d.items())[:2]:
print('{}:{}'.format(d[i][0], d[i][1]))
a:1
b:2

boolean retrieval, indexing phase

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.

Categories

Resources