Say I have a list of list like this: (suppose you have no idea how many lists in this list)
list=[['food','fish'],['food','meat'],['food','veg'],['sports','football']..]
how can I merge the items in the list like the following:
list=[['food','fish','meat','veg'],['sports','football','basketball']....]
i.e, merge all the nested lists into the same list if they contain one of the same items.
Use defaultdict to make a dictionary that maps a type to values and then get the items:
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> items = [['food','fish'],['food','meat'],['food','veg'],['sports','football']]
>>> for key, value in items:
... d[key].append(value)
...
>>> [[key] + values for key, values in d.items()]
[['food', 'fish', 'meat', 'veg'], ['sports', 'football']]
The "compulsory" alternative to defaultdict which can work better for data that's already in order of the key and if you don't want to build data structures on it (ie, just work on groups)...
data = [['food','fish'],['food','meat'],['food','veg'],['sports','football']]
from itertools import groupby
print [[k] + [i[1] for i in v] for k, v in groupby(data, lambda L: L[0])]
But defaultdict is more flexible and easier to understand - so go with #Blender's answer.
Related
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()
This is my list:
volume = [['1.986', '3000'], ['1.987', '2000'], ['1.986', '700'],['1.987', '4000']]
How can I get the sum of volume[1] when volume[0] is the same price?
results = [['1.986', '3700'], ['1.987', '6000']]
Dictionaries would be a good data structure to use here. The default dict holds unique strings as the keys and assumes empty values are 0 because I set it to be based off of int.
from collections import defaultdict
d = defaultdict(int)
for v in volume:
d[v[0]] += int(v[1])
print d
If you need a list afterwards you can use a list comprehension:
list_version = [[key, value] for key,value in d]
I want to create a dictionary out of a list that has several similar elements. But, in the dictionary, all these similar elements must have the same key.
d_dict={}
lst=['A1','A2','A3','2e','2o','2m']
for element in lst:
if element.startswith('A'):
d_dict[1].append(element)
elif element.startswith('2'):
d_dict[2].append(element)
print(d_dict)
My output should look like:
d_dict={1:['A1','A2','A3'],2:['2e','2o','2m']}
thanks.
You're looking for collections.defaultdict:
>>> from collections import defaultdict
>>> d_dict = defaultdict(list)
>>> for element in lst:
... if element.startswith('A'):
... d_dict[1].append(element)
... elif element.startswith('2'):
... d_dict[2].append(element)
...
>>> print d_dict
defaultdict(<type 'list'>, {1: ['A1', 'A2', 'A3'], 2: ['2e', '2o', '2m']})
So pretty much, with this module, your code is exactly the same. You only need to make your dictionary a type defaultdict so that you can have lists as values without having to create any.
You need to create the lists before appending something to them:
for element in lst:
if element.startswith('A'):
if 1 not in d_dict: # if it is not already created
d_dict[1] = [element] # add list with the current element
else:
d_dict[1].append(element)
elif element.startswith('2'):
if 2 not in d_dict:
d_dict[2] = [element]
else:
d_dict[2].append(element)
The only problem I see in your code is that you don't initialize the sublists, so d_dict[1] doesn't exist. But you can avoid having to do this altogether if you use a defaultdict.
from collections import defaultdict
d_dict=defaultdict(list)
d_dict[1].extend(e for e in lst if e.startswith('A'))
d_dict[2].extend(e for e in lst if e.startswith('2'))
If you wanted your code to be more flexible, this will work with any strings, not just those starting with A and 2. You can use the defaultdict class from collections.
from collections import defaultdict
values = ['A1','A2','A3','2e','2o','2m']
grouped = defaultdict(list)
for i in values:
grouped[i[0]].append(i)
print(dict(grouped))
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.
This question already has answers here:
How do I sort a dictionary by value?
(34 answers)
Closed 3 years ago.
Assume that I have a dict.
data = {1:'b', 2:'a'}
And I want to sort data by 'b' and 'a' so I get the result
'a','b'
How do I do that?
Any ideas?
To get the values use
sorted(data.values())
To get the matching keys, use a key function
sorted(data, key=data.get)
To get a list of tuples ordered by value
sorted(data.items(), key=lambda x:x[1])
Related: see the discussion here: Dictionaries are ordered in Python 3.6+
If you actually want to sort the dictionary instead of just obtaining a sorted list use collections.OrderedDict
>>> from collections import OrderedDict
>>> from operator import itemgetter
>>> data = {1: 'b', 2: 'a'}
>>> d = OrderedDict(sorted(data.items(), key=itemgetter(1)))
>>> d
OrderedDict([(2, 'a'), (1, 'b')])
>>> d.values()
['a', 'b']
From your comment to gnibbler answer, i'd say you want a list of pairs of key-value sorted by value:
sorted(data.items(), key=lambda x:x[1])
Thanks for all answers.
You are all my heros ;-)
Did in the end something like this:
d = sorted(data, key = data.get)
for key in d:
text = data[key]
Sort the values:
sorted(data.values())
returns
['a','b']
I also think it is important to note that Python dict object type is a hash table (more on this here), and thus is not capable of being sorted without converting its keys/values to lists. What this allows is dict item retrieval in constant time O(1), no matter the size/number of elements in a dictionary.
Having said that, once you sort its keys - sorted(data.keys()), or values - sorted(data.values()), you can then use that list to access keys/values in design patterns such as these:
for sortedKey in sorted(dictionary):
print dictionary[sortedKeY] # gives the values sorted by key
for sortedValue in sorted(dictionary.values()):
print sortedValue # gives the values sorted by value
Hope this helps.
You could created sorted list from Values and rebuild the dictionary:
myDictionary={"two":"2", "one":"1", "five":"5", "1four":"4"}
newDictionary={}
sortedList=sorted(myDictionary.values())
for sortedKey in sortedList:
for key, value in myDictionary.items():
if value==sortedKey:
newDictionary[key]=value
Output: newDictionary={'one': '1', 'two': '2', '1four': '4', 'five': '5'}
In your comment in response to John, you suggest that you want the keys and values of the dictionary, not just the values.
PEP 256 suggests this for sorting a dictionary by values.
import operator
sorted(d.iteritems(), key=operator.itemgetter(1))
If you want descending order, do this
sorted(d.iteritems(), key=itemgetter(1), reverse=True)
no lambda method
# sort dictionary by value
d = {'a1': 'fsdfds', 'g5': 'aa3432ff', 'ca':'zz23432'}
def getkeybyvalue(d,i):
for k, v in d.items():
if v == i:
return (k)
sortvaluelist = sorted(d.values())
sortresult ={}
for i1 in sortvaluelist:
key = getkeybyvalue(d,i1)
sortresult[key] = i1
print ('=====sort by value=====')
print (sortresult)
print ('=======================')