How to find all specific dict objects with static value in dictionary - python

I have many dicts in my dictionary sturcture like
x = {'Shoes': 'http://www./', 'sub_categories': []}
It appears in some lists in dictionary
is there some possibility to remove all such objects like 'x' from my dictionary?

You can use a dict comprehension to iterate over the items, and check if the value is a list using isinstance.
>>> d = {'Shoes': 'http://www./', 'sub_categories': []}
>>> {k:v for k,v in d.items() if not isinstance(v, list)}
{'Shoes': 'http://www./'}

Related

how to combine the common key and join the values in the dictionary python

I have one list which contain a few dictionaries.
[{u'TEXT242.txt': u'work'},{u'TEXT242.txt': u'go to work'},{u'TEXT1007.txt': u'report'},{u'TEXT797.txt': u'study'}]
how to combine the dictionary when it has the same key. for example:
u'work', u'go to work'are under one key:'TEXT242.txt', so that i can remove the duplicated key.
[{u'TEXT242.txt': [u'work', u'go to work']},{u'TEXT1007.txt': u'report'},{u'TEXT797.txt': u'study'}]
The setdefault method of dictionaries is handy here... it can create an empty list when a dictionary key doesn't exist, so that you can always append the value.
dictlist = [{u'TEXT242.txt': u'work'},{u'TEXT242.txt': u'go to work'},{u'TEXT1007.txt': u'report'},{u'TEXT797.txt': u'study'}]
newdict = {}
for d in dictlist:
for k in d:
newdict.setdefault(k, []).append(d[k])
from collections import defaultdict
before = [{u'TEXT242.txt': u'work'},{u'TEXT242.txt': u'go to work'},{u'TEXT1007.txt': u'report'},{u'TEXT797.txt': u'study'}]
after = defaultdict(list)
for i in before:
for k, v in i.items():
after[k].append(v)
out:
defaultdict(list,
{'TEXT1007.txt': ['report'],
'TEXT242.txt': ['work', 'go to work'],
'TEXT797.txt': ['study']})
This technique is simpler and faster
than an equivalent technique using dict.setdefault()

create ordered dict from list comprehension?

Here is a list comprehension:
L = [{k: d[k](v) for (k, v) in l.iteritems()} for l in L]
where
L is a list of ordered dictionaries (i.e. objects of collections.OrderedDict), where the dictionaries have the same set of keys.
d is another ordered dictionary, which also has the same set of keys as the previous ordered dictionaries.
For each key, d[key] is a function which can apply to L[i][key], i.e. d[key](L[i][key]).
All the given dictionaries are ordered dicts, and have the same order in their keys.
But the code will create an unordered dictionary. How can I create an ordered dict in the same key order as the given ordered dictionaries?
collections.OrderedDict is nothing but a dict, which remembers the order in which the elements are included in it. So you can create one with its constructor like this
[OrderedDict((k, d[k](v)) for (k, v) in l.iteritems()) for l in L]
Python dictionary unlike C++ dictionary are unordered because it uses hash for its keys. Analternative would be to use an ordered specialization of python dictionary called collections.OrdredDict.
This would turn your declaration as
from collections import OrderedDict
L = [OrderedDict((k, d[k](v)) for (k, v) in l.iteritems()) for l in L]

Sort dictionary by specific order (list of keys)

I am trying to sort a dictionary based on the order that its keys appears in a list.
First element of the list would be the first element of the dictionary. At the end the dictionary keys wiould be in the same order as in the provided list...
I can sort by value with this code
newlist = sorted(product_list, key=lambda k: k['product'])
but cant do it for a list
thanks for any help!
from collections import OrderedDict
new_dict = OrderedDict((k, old_dict[k]) for k in key_list)
Having said that, there's probably a better way to solve your problem than using an OrderedDict
If some keys are missing, you'll need to use one of
new_dict = OrderedDict((k, old_dict.get(k)) for k in key_list)
or
new_dict = OrderedDict((k, old_dict[k]) for k in key_list if k in old_dict)
depending on how you want to handle the missing keys.
In Python (and most languages) dictionaries are unsorted, so you can't "sort" a dictionary.
You can retrieve and sort the keys and iterate through those:
for key in sorted(product_list.keys()):
item = product_list[key]
item.doSomething()
Or you can use a OrderDict, like so:
from collections import OrderedDict
And then build the dictionary in the required order (which is up to you to determine) but below we sort using the keys:
product_list = OrderDict(sorted(product_list.items(), key=lambda k: k[0]))
For reference, Dict.items() returns a list of tuples in the form:
[(key1, value1), (key2, value2) , ... , (keyN, valueN)]
By definition, a dictionary is unordered. You can use OrderedDict from collections as seen at http://docs.python.org/2/library/collections.html#collections.OrderedDict as a drop-in replacement.

Selecting elements of a Python dictionary greater than a certain value

I need to select elements of a dictionary of a certain value or greater. I am aware of how to do this with lists, Return list of items in list greater than some value.
But I am not sure how to translate that into something functional for a dictionary. I managed to get the tags that correspond (I think) to values greater than or equal to a number, but using the following gives only the tags:
[i for i in dict if dict.values() >= x]
.items() will return (key, value) pairs that you can use to reconstruct a filtered dict using a list comprehension that is feed into the dict() constructor, that will accept an iterable of (key, value) tuples aka. our list comprehension:
>>> d = dict(a=1, b=10, c=30, d=2)
>>> d
{'a': 1, 'c': 30, 'b': 10, 'd': 2}
>>> d = dict((k, v) for k, v in d.items() if v >= 10)
>>> d
{'c': 30, 'b': 10}
If you don't care about running your code on python older than version 2.7, see #opatut answer using "dict comprehensions":
{k:v for (k,v) in dict.items() if v > something}
While nmaier's solution would have been my way to go, notice that since python 2.7+ there has been a "dict comprehension" syntax:
{k:v for (k,v) in dict.items() if v > something}
Found here: Create a dictionary with list comprehension in Python. I found this by googling "python dictionary list comprehension", top post.
Explanation
{ .... } includes the dict comprehension
k:v what elements to add to the dict
for (k,v) in dict.items() this iterates over all tuples (key-value-pairs) of the dict
if v > something a condition that has to apply on every value that is to be included
You want dict[i] not dict.values(). dict.values() will return the whole list of values that are in the dictionary.
dict = {2:5, 6:2}
x = 4
print [dict[i] for i in dict if dict[i] >= x] # prints [5]

Refactoring with python dictionary comprehension

I have 2 dictionary which contain the same keys but the value pairs are different. Let's make dictA and dictB represent the two dictionaries in question.
dictA = {'key1':'Joe', 'key2':'Bob'}
dictB = {'key1':'Smith', 'key2':'Johnson'}
Currently, I am creating a new dictionary based the common occurring keys through a nested if statement. In doing so, the values that share a key are contained within a list, in the new dictionary. See this done below:
dictAB = {} # Create a new dictionary
# Create a list container for dictionary values
for key in dictA.keys():
dictAB[key] = []
# Iterate through keys in both dictionaries
# Find matching keys and append the respective values to the list container
for key, value in dictA.iteritems():
for key2, value2 in dictB.iteritems():
if key == key2:
dictAB[key].append(value)
dictAB[key].append(value2)
else:
pass
How can this be made into a more clean structure using python dictionary comprehension?
Use sets or key views (python 2.7):
dictAB = {k: [dictA[k], dictB[k]] for k in dictA.viewkeys() & dictB.viewkeys()}
Before 2.7:
dictAB = dict((k, [dictA[k], dictB[k]]) for k in set(dictA) & set(dictB))
In python 3, you can use the .keys method for such operations directly, as they are implemented as views:
dictAB = {k: [dictA[k], dictB[k]] for k in dictA.keys() & dictB.keys()}
Demo (python 2.7):
>>> dictA = {'key1':'Joe', 'key2':'Bob'}
>>> dictB = {'key1':'Smith', 'key2':'Johnson'}
>>> dictAB = {k: [dictA[k], dictB[k]] for k in dictA.viewkeys() & dictB.viewkeys()}
>>> print dictAB
{'key2': ['Bob', 'Johnson'], 'key1': ['Joe', 'Smith']}
The & operator on either two sets or on a dict view creates the intersection of both sets; all keys that are present in both sets.
By using an intersection of the keys, this code will work even if either dictA or dictB has keys that do not appear in the other dictionary. If you are absolutely sure the keys will always match, you could just iterate over either dict directly without the intersection:
dictAB = {k: [dictA[k], dictB[k]] for k in dictA}
dictAB = { key: [dictA[key],dictB[key]] for key in dictA if key in dictB }

Categories

Resources