dico = {"dico": {1:"bailler",2:"bailler",3:"percer",4:"calculer",5:"calculer",6:"trouer",7:"bailler",8:"découvrir",9:"bailler",10:"miser",11:"trouer",12:"changer"}}
I have a big dictionary of dictionaries like that. I want to put identic elements together in sets. So create a kind of condition which will say if the values of "dico" are equal put them in a set():
b=[set(1,2,7,9),set(3),set(4,5),set(6,11),set(8),set(10),set(12)]
I don't know if that question has already been asked but as a new pythonner I don't have all the keys... ^^
Thank you for you answers
I would reverse your dictionary and have the value a set(), then return all the values.
>>> from collections import defaultdict
>>>>my_dict= {"dico": {1:"bailler",2:"bailler",3:"percer",4:"calculer",5:"calculer",6:"trouer",7:"bailler",8:"découvrir",9:"bailler",10:"miser",11:"trouer",12:"changer"}}
>>> my_other_dict = defaultdict(set)
>>> for dict_name,sub_dict in my_dict.iteritems():
for k,v in sub_dict.iteritems():
my_other_dict[v].add(k) #the value, i.e. "bailler" is now the key
#e.g. {"bailler":set([1,2,9,7]),...
>>> [v for k,v in my_other_dict.iteritems()]
[set([8]), set([1, 2, 9, 7]), set([3]), set([4, 5]), set([12]), set([11, 6]), set([10])]
Of course as cynddl has pointed out, if your index in a list will always be the "key", simply enumerate a list and you won't have to store original data as a dictionary, nor use sets() as indices are unique.
You should write your data this way:
dico = ["bailler", "bailler", "percer", "calculer", "calculer", "trouer", "bailler", "découvrir", "bailler", "miser", "trouer", "changer"]
If you want to count the number of identic elements, use collections.Counter:
import collections
counter=collections.Counter(dico)
print(counter)
which returns a Counter object:
Counter({'bailler': 4, 'calculer': 2, 'trouer': 2, 'd\xc3\xa9couvrir': 1, 'percer': 1, 'changer': 1, 'miser': 1})
The dict.setdefault() method can be handy for tasks like this, as well as dict.items() which iterates through the (key, value) pairs of the dictionary.
>>> dico = {"dico": {1:"bailler",2:"bailler",3:"percer",4:"calculer",5:"calcul
er",6:"trouer",7:"bailler",8:"découvrir",9:"bailler",10:"miser",11:"trouer",12:"
changer"}}
>>> newdict = {}
>>> for k, subdict in dico.items():
... newdict[k] = {}
... for subk, subv in subdict.items():
... newdict[k].setdefault(subv, set()).add(subk)
...
>>> newdict
{'dico': {'bailler': {1, 2, 9, 7}, 'miser': {10}, 'découvrir': {8}, 'calculer':
{4, 5}, 'changer': {12}, 'percer': {3}, 'trouer': {11, 6}}}
>>> newdict['dico'].values()
dict_values([{1, 2, 9, 7}, {10}, {8}, {4, 5}, {12}, {3}, {11, 6}])
Related
Reading about data structures and have a question.
This is a dictionary:
example = {'the': 8,
'metal': 8,
'is': 23,
'worth': 3,
'many': 3,
'dollars': 2,
'right': 2}
How to store to a variable the value of a key/value pair by order?
For example, how to store the value of the third pair, which is 23?
Tried this, which is not correct:
for k in example:
if k == 3:
a_var = example(k)
If you know the key/values have been inserted in the correct order, you can use islice() to get the third key/value pair. This has the benefit of not needing to create a whole list of values and is a bit simpler than explicitly writing a loop:
from itertools import islice
example = {
'the': 8,
'metal': 8,
'is': 23,
'worth': 3,
'many': 3,
'dollars': 2,
'right': 2
}
key, val = next(islice(example.items(), 2, None))
# 'is', 23
If you only want the value instead of the key/value pair, then of course you can pass values() instead of items() to islice():
val = next(islice(example.values(), 2, None))
# 23
This does what you need:
example = {'the': 8,
'metal': 8,
'is': 23,
'worth': 3,
'many': 3,
'dollars': 2,
'right': 2}
k=0
for key in example:
k+=1
if k == 3:
a_var = example[key]
print(a_var)
Output:
23
If you really think you need this:
def find( example, ordinal):
for k,value in enumerate(example.values()):
if k == ordinal:
return value
or
def find( example, ordinal):
return list(example.values())[ordinal]
a_var=example[list(example.keys())[3-1]]
given dictionary and limit for the number of keys for the new dictionary. In the new dictionary we should have the highest number of values from given dictionary.
the given is:
dict = {'apple':5, 'pears':4, 'orange':3, 'kiwi':3, 'banana':1
I want to get a new dictionary with the highest value with key.
new is
{'apple':5}
because there should be only one
if the limit is 2.
{'apple':5, 'pears':4}
because there are three values but the limit is 2 it we don't take anything. I tried
if the limit is 3. It's still
{'apple':5, 'pears':4}
because I can't add orange. If I add it will be more than the limit.
new = {}
while len(new) < limit:
then I have to append the highest value with key in new until I reach
the limit. I should not add the key if it will more than the limit.
I believe your problem is that you have
while len(new) < limit:
it needs to be while len(new) <= limit:
Whole code being a function:
def f(d,limit):
return dict(sorted(d.items(),key=lambda x: -x[1])[:limit])
And now:
print(f(d,1))
Is:
{'apple': 5}
And:
print(f(d,2))
Is:
{'apple': 5, 'pears': 4}
Note that if the dictionary is always sorted by values like the dictionary you have now, do:
def f(d,limit):
return dict(d.items()[:limit])
You can just use most_common() from collections.Counter():
from collections import Counter
def largest(dct, n):
return dict(Counter(dct).most_common(n))
print(largest(dct={'apple':5, 'pears':4, 'orange':3, 'kiwi':3, 'banana':1}, n=2))
# {'apple': 5, 'pears': 4}
print(largest(dct={'apple':5, 'pears':4, 'orange':3, 'kiwi':3, 'banana':1}, n=3))
# {'apple': 5, 'pears': 4, 'orange': 3}
Or even with heapq.nlargest():
from heapq import nlargest
from operator import itemgetter
def largest(dct, n):
return dict(nlargest(n, dct.items(), key=itemgetter(1)))
print(largest(dct={'apple':5, 'pears':4, 'orange':3, 'kiwi':3, 'banana':1}, n=2))
# {'apple': 5, 'pears': 4}
print(largest(dct={'apple':5, 'pears':4, 'orange':3, 'kiwi':3, 'banana':1}, n=3))
# {'apple': 5, 'pears': 4, 'orange': 3}
Now, I wanna convert an array to a dict like this:
dict = {'item0': arr[0], 'item1': arr[1], 'item2': arr[2]...}
How to solve this problem elegantly in python?
You could use enumerate and a dictionary comprehension:
>>> arr = ["aa", "bb", "cc"]
>>> {'item{}'.format(i): x for i,x in enumerate(arr)}
{'item2': 'cc', 'item0': 'aa', 'item1': 'bb'}
Suppose we have a list of ints:
We can use a dict comprehension
>>> l = [3, 2, 4, 5, 7, 9, 0, 9]
>>> d = {"item" + str(k): l[k] for k in range(len(l))}
>>> d
{'item5': 9, 'item4': 7, 'item7': 9, 'item6': 0, 'item1': 2, 'item0': 3, 'item3': 5, 'item2': 4}
simpleArray = [ 2, 54, 32 ]
simpleDict = dict()
for index,item in enumerate(simpleArray):
simpleDict["item{0}".format(index)] = item
print(simpleDict)
Ok, first line Is the input, second line is an empty dictionary. We will fill it on the fly.
Now we need to iterate, but normal iteration as in C is considered non Pythonic. Enumerate will give the index and the item we need from the array. See this: Accessing the index in Python 'for' loops.
So in each iteration we will be getting an item from array and inserting in the dictionary with a key from the string in brackets. I'm using format since use of % is discouraged. See here: Python string formatting: % vs. .format.
At last we will print. Used print as function for more compatibility.
you could use a dictionary comprehension
eg.
>>> x = [1,2,3]
>>> {'item'+str(i):v for i, v in enumerate(x)}
>>> {'item2': 3, 'item0': 1, 'item1': 2}
Use dictionary comprehension: Python Dictionary Comprehension
So it'll look something like:
d = {"item%s" % index: value for (index, value) in enumerate(arr)}
Note the use of enumerate to give the index of each value in the list.
You can also use the dict() to construct your dictionary.
d = dict(('item{}'.format(i), arr[i]) for i in xrange(len(arr)))
Using map, this could be solved as:
a = [1, 2, 3]
d = list(map(lambda x: {f"item{x[0]}":x[1]}, enumerate(a)))
The result is:
[{'item0': 1}, {'item1': 2}, {'item2': 3}]
Assuming I have the following structure:
listoflist = [[0,1,2,3,4],[2,4,2,3,4],[3,4,5,None,3],...]
Assuming I have:
headers = ["A","B","C","D","E"]
I want to convert each to:
listofobj = [{"A":0,"B":2,"C":3,"D":4,"E":5},{"A":2,"B":4,"C":2,"E":4}]
What is the best way to do this?
Note that D: does not show up for the 3rd dictionary in the converted list because it is None. Am looking for the most optimal way/quickest performance for this.
You can use list comprehension to perform an operation on each element of a list, the zip builtin function to match each element of headers against the corresponding element in listoflist, and the dict builtin function to convert each of those into a dictionary. So, the code you want is
listofobj = [dict(zip(headers, sublist)) for sublist in listoflist]
Removing None values is probably best done in another function:
def without_none_values(d):
return {k:d[k] for k in d if d[k] is not None}
With that function, we can complete the list with
listofobj = [without_none_values(dict(zip(headers, sublist))) for sublist in listoflist]
Easy to do in Python >= 2.7 using dictionary comprehension:
listofobj = [
{ k: v for k, v in zip(headers, sublist) if v is not None }
for sublist in listoflist
]
In Python 2.6 one needs to use dict:
listofobj = [
dict((k, v) for k, v in zip(headers, sublist) if v is not None)
for sublist in listoflist
]
I would iterate through each list, and zip it with the list of headers.
headers = ["A","B","C","D","E"]
listoflist = [[0,1,2,3,4],[2,4,2,3,4],[1,2,3,4,4],[5,6,7,8,9],[0,9,7,6,5]]
[dict(zip(headers, sublist)) for sublist in listoflist]
Output
[{'A': 0, 'C': 2, 'B': 1, 'E': 4, 'D': 3},
{'A': 2, 'C': 2, 'B': 4, 'E': 4, 'D': 3},
{'A': 1, 'C': 3, 'B': 2, 'E': 4, 'D': 4},
{'A': 5, 'C': 7, 'B': 6, 'E': 9, 'D': 8},
{'A': 0, 'C': 7, 'B': 9, 'E': 5, 'D': 6}]
Create a Pandas Series object from each of the lists in your listoflist, using headers as the index.
Then drop None values using dropna() method. And finally create a dictionary from each Series.
import pandas as pd
listofobj = [dict(pd.Series(x, index = headers).dropna()) for x in listoflist]
[x for x in l if x is not None] keeps all values that are not None
We enumerate over headers and access the element at the corresponding index in each sublist of listoflist using l[ind].
if l[ind] will be True if the value is not None so we use that element as a key or else ignore it if the value is None.
list_of_obj = [dict(zip([x for ind ,x in enumerate(headers) if l[ind] is not None],[x for x in l if x is not None])) for l in listoflist]
This question already has answers here:
How do I sort a dictionary by value?
(34 answers)
Closed last month.
The only methods I found work for python2 or return only list of tuples.
Is it possible to sort dictionary, e.g. {"aa": 3, "bb": 4, "cc": 2, "dd": 1}, by its values?
Order of sorted dictionary I want to achieve is from largest to smallest. I want results to look like this:
bb 4
aa 3
cc 2
dd 1
And after sorting I want to store it into a text file.
itemgetter (see other answers) is (as I know) more efficient for large dictionaries but for the common case, I believe that d.get wins. And it does not require an extra import.
>>> d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
>>> for k in sorted(d, key=d.get, reverse=True):
... k, d[k]
...
('bb', 4)
('aa', 3)
('cc', 2)
('dd', 1)
Note that alternatively you can set d.__getitem__ as key function which may provide a small performance boost over d.get.
from collections import OrderedDict
from operator import itemgetter
d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
print(OrderedDict(sorted(d.items(), key = itemgetter(1), reverse = True)))
prints
OrderedDict([('bb', 4), ('aa', 3), ('cc', 2), ('dd', 1)])
Though from your last sentence, it appears that a list of tuples would work just fine, e.g.
from operator import itemgetter
d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
for key, value in sorted(d.items(), key = itemgetter(1), reverse = True):
print(key, value)
which prints
bb 4
aa 3
cc 2
dd 1
You can sort by values in reverse order (largest to smallest) using a dictionary comprehension:
{k: d[k] for k in sorted(d, key=d.get, reverse=True)}
# {'b': 4, 'a': 3, 'c': 2, 'd': 1}
If you want to sort by values in ascending order (smallest to largest)
{k: d[k] for k in sorted(d, key=d.get)}
# {'d': 1, 'c': 2, 'a': 3, 'b': 4}
If you want to sort by the keys in ascending order
{k: d[k] for k in sorted(d)}
# {'a': 3, 'b': 4, 'c': 2, 'd': 1}
This works on CPython 3.6+ and any implementation of Python 3.7+ because dictionaries keep insertion order.
Another way is to use a lambda expression. Depending on interpreter version and whether you wish to create a sorted dictionary or sorted key-value tuples (as the OP does), this may even be faster than the accepted answer.
d = {'aa': 3, 'bb': 4, 'cc': 2, 'dd': 1}
s = sorted(d.items(), key=lambda x: x[1], reverse=True)
for k, v in s:
print(k, v)
To sort dictionary, we could make use of operator module. Here is the operator module documentation.
import operator #Importing operator module
dc = {"aa": 3, "bb": 4, "cc": 2, "dd": 1} #Dictionary to be sorted
dc_sort = sorted(dc.items(),key = operator.itemgetter(1),reverse = True)
print dc_sort
Output sequence will be a sorted list :
[('bb', 4), ('aa', 3), ('cc', 2), ('dd', 1)]
If we want to sort with respect to keys, we can make use of
dc_sort = sorted(dc.items(),key = operator.itemgetter(0),reverse = True)
Output sequence will be :
[('dd', 1), ('cc', 2), ('bb', 4), ('aa', 3)]
To sort a dictionary and keep it functioning as a dictionary afterwards, you could use OrderedDict from the standard library.
If that's not what you need, then I encourage you to reconsider the sort functions that leave you with a list of tuples. What output did you want, if not an ordered list of key-value pairs (tuples)?