How to access key in Python dictionary - python

I know it's possible to traverse a dictionary by using iteritems() or keys(). But what if I got a list of dics such as: l = [{'a': 1}, {'b': 2}, {'c': 3}] and I want to compose a string using its keys, e.g., s = 'a, b, c'?
One solution is to copy all the keys into a list in advance, and compose the string I want. Just wondering if there is a better solution.

You can use itertools.chain() for it and make use of the fact that iterating over a dict will yield its keys.
import itertools
lst = [{'a': 1}, {'b': 2}, {'c': 3}]
print ', '.join(itertools.chain(*lst))
This also works it there are dicts with more than one element.
If you do not want duplicate elements, use a set:
print ', '.join(set(itertools.chain(*lst)))

Assuming each dictionary will only have a single key:
', '.join(a.keys()[0] for a in l)
if not, maybe something like:
>>> l = [{'a': 1, 'd': 4}, {'b': 2}, {'c': 3}]
>>> ', '.join(', '.join(a.keys()) for a in l)
'a, d, b, c'

Iterate over the dictionaries and then over the keys of each dictionary:
>>> lst = [{'a': 1}, {'b': 2}, {'c': 3}]
>>> ', '.join(key for dct in lst for key in dct.keys())
'a, b, c'

Try this:
''.join([i.keys()[0] for i in l])
You can put any delimiter you want inside of the quotes. Just bear in mind that the dictionary isn't ordered, so you may get weird looking strings as a result of this.

Related

Remove the duplicate from list of dict in python

I have dict like this
d=[{'a':1,'b':2},{'a':2,'b':2},{'a':3},{'a':1}]
So i need like
d=[{'a':1,'b':2},{'a':2,'b':2},{'a':3}]
Remove duplicate
Learn more about Python data types and theirs functions. Here is one tutorial for dictionaries
As what I know using list of dictionaries is a bad practice
Here is my solution it could be not so elegant, but it is working. Also remove duplicates means remove ALL of them, so I remove all list elements where they were repeated.
d = [{'a': 1, 'b': 2}, {'a': 2, 'b': 2}, {'a': 3}, {'a': 1}]
temp = []
for i in d:
for x, y in i.items():
temp_var = [x, y]
if temp_var in temp:
d.pop(d.index(i))
else:
temp.append(temp_var)
print(d)
# result [{'a': 1, 'b': 2}, {'a': 3}]
P.S.: Keep learning and have a nice day :)

how to add same dictionary to a list with modified value

csv={“a”:0}
list_=[]
for i in range(2):
csv["a"]+=1
list_.append(csv)
print(list_,csv)
I am getting output like this:
[{'a': 2}, {'a': 2}]
I need to get an output like this
[{'a': 1}, {'a': 2}]
Because python pass variables to functions as reference and not as value, you need to pass a copy of the original dictionnary to list_.append():
csv={"a":0}
list_=[]
for i in range(2):
csv["a"]+=1
list_.append(dict(csv))
print(list_)
You can do a list-comprehension:
list_ = [{'a': x} for x in range(1, 3)]
# [{'a': 1}, {'a': 2}]

Sorting identical keys in a dictionary [duplicate]

This question already has answers here:
How can one make a dictionary with duplicate keys in Python?
(9 answers)
Closed 6 years ago.
I just started learning python and was wondering if its possible to pair two identical keys?
example:
my_dict= {1:a,3:b,1:c}
and I want to make a new dict, something like this:
new_dict= {1:{a,c},3:{b}}
thanks for the help
You can't have identical keys, that is the definition of dictionary. As soon as you add again the same key, the previous entry is deleted
You cannot have repeated dictionary keys in python.
From what I understand, you're trying to combine the two dictionaries. Given that you cannot have same keys in a dictionary, I'll suppose you have two distinct dictionaries you'd like to combine to obtain your combination.
Ex:
dic1 = {'a': 1, 'b': 2, 'c': 3}
dic2 = {'c': 4, 'd': 5, 'e': 6}
And the combination would produce:
{'a': {1}, 'b': {2}, 'c':{3, 4}, 'd': {4}, 'e': {6}}
You could use this Example:
from itertools import chain
from collections import defaultdict
dic1 = {'A': 1, 'B': 2, 'C': 3}
dic2 = {'C': 4, 'D': 5, 'E': 6}
dic = defaultdict(set)
for k, v in chain(dic1.items(), dic2.items()):
dic[k].add(v)
print(dict(dic))
Something to note:
'dic' is not exactly a dict(), it's of type 'defaultdict', but you can do dict(dic) to make it so.
You could instead of using set, use list in the defaultdict() argument and have a dictionary as so:
{'a': [1], 'b': [2], 'c':[3, 4], 'd': [4], 'e': [6]}
But to do so, dic[k].append(v) would be used in the for loop. You add items to sets, append to lists.
Dictionaries in Python, or any hash-able type for that matter, will not allow duplicate keys. If two duplicate keys are found in a dictionary, the key farthest in the dictionary will be persevered. This behavior can be obsevered first hand:
>>> my_dict= {1:'a',3:'b',1:'c'}
>>> my_dict
{1: 'c', 3: 'b'}
>>> my_dict= {1:'c',3:'b',1:'a'}
>>> my_dict
{1: 'a', 3: 'b'}
>>>
The Python documentation for dict()s touches on this matter:
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).[...].
(emphasis mine)

Split a list on a separator - keeping the separator in the group

I have a weird data structure that is returned to me by an external service I have no control over.
The data is essentially a list of dictionaries, but chopped up in a strange way: it is returned as a list of dictionaries, where each of these dictionaries has a single key. Taking multiple elements from this list yields all the keys in the dictionary.
In code:
[ {'id': 1}, {'a': a}, {'b': b}, {'c': c},
{'id': 2}, {'a': a}, {'b': b}, {'c': c},
{'id': 3}, {'a': a}, {'b': b}, {'c': c},
...
]
Every dictionary that I want to reconstruct starts with the id dictionary. After I find the id key, I need to take all the values from the list until I find another id.
My current solution is:
def split_groups(data, key='id'):
groups = []
for e in data:
if key in e: # begin new group
groups.append(list())
groups[-1].append(e)
return groups
which works, but it's ugly. I know about itertools.groupby: however, I can't really understand how to use it.
The result of this line:
[(k, list(g)) for k, g in groupby(data, lambda d: d.get('id') is not None)]
is:
[(True, [{'id': 1}]),
(False, [{'a': 1}, {'b': 2}, {'c': 3}]),
(True, [{'id': 2}]),
(False, [{'a': 1}, {'b': 2}, {'c': 3}]),
(True, [{'id': 3}]),
(False, [{'a': 1}, {'b': 2}, {'c': 3}])]
As you can see the id dictionary ends up in a different group than the following values.
What am I doing wrong?
After Sumukh Barve's answer, I guess that groupby just isn't the right tool for my job. My current code will do for production; just for fun, I rewrote it like this:
def split_groups(data, key='id'):
if not data:
return []
predicate = lambda d: key not in d
head, tail = data[0], data[1:]
group = [[head] + list(takewhile(predicate, tail))]
rest = list(dropwhile(predicate, tail))
group.extend(split_groups(rest, key))
return group
which is a much less efficient, much less readable, much more OCD-appealing form.
Thanks everyone for your help!
Just in case that somebody one day stumbles into my same problem, I am attaching the full solution with some example data.
From the docs:
It (itertools.groupby) generates a break or new group every time the value of the key function changes . . .
In that sense, itertools.groupby is similar to str.split; the difference being that the split sequence is also included in the output.
"1,2,3".split(",") ==> ["1", "2", "3"]
"1,2,3".splitLikeGroupBy(",") ==> ["1", ",", "2", ",", "3"]
So, you aren't doing anything wrong.
Also, I'd say that your solution is good.
But, if you insist on using itertools.groupby, try this:
a = [(k, list(g)) for k, g in groupby(data, lambda d: d.get('id') is not None)];
[a[i][1] + a[i+1][1] for i in range(len(a)) if i % 2 == 0]
The first line comes straight from your code. The second is some simple processing.
Suggestion:
Instead of working with a list of list of single-element dictionaries, you may want to work with a list of multi-element dictionaries.
That is, instead of working with this:
[
[{"id": "id1"}, {"a": "a1"}],
[{"id": "id2"}, {"a": "a2"}], ...
]
You might want to work with this:
[
{"id": "id1", "a": "a1"},
{"id": "id2", "a": "a2"}, ...
]
Hope this helps.
IMHO, this is not a trivial task.
A solution in two lines :
ind=[i for i,d in enumerate(l) if 'id' in d]
slices=[l[a:b] for (a,b) in zip(ind,ind[1:]+[len(l)])]

Python adding dictionary values with same key within a list

i just picked up python not too long ago.
An example below
i have a dictionary within a list
myword = [{'a': 2},{'b':3},{'c':4},{'a':1}]
I need to change it to the output below
[{'a':3} , {'b':3} , {'c':4}]
is there a way where i can add the value together? I tried using counter, but it prints out the each dict out.
what i did using Counter:
for i in range(1,4,1):
text = myword[i]
Print Counter(text)
The output
Counter({'a': 2})
Counter({'b': 3})
Counter({'c': 4})
Counter({'a': 1})
i have read the link below but what they compared was between 2 dict.
Is there a better way to compare dictionary values
Thanks!
Merge dictionaries into one dictionary (Counter), and split them.
>>> from collections import Counter
>>> myword = [{'a': 2}, {'b':3}, {'c':4}, {'a':1}]
>>> c = Counter()
>>> for d in myword:
... c.update(d)
...
>>> [{key: value} for key, value in c.items()]
[{'a': 3}, {'c': 4}, {'b': 3}]
>>> [{key: value} for key, value in sorted(c.items())]
[{'a': 3}, {'b': 3}, {'c': 4}]

Categories