python sort list by custom criteria - python

I have following data read from csv :
venues =[{'capacity': 700, 'id': 1, 'name': 'AMD'},
{'capacity': 2000, 'id': 2, 'name': 'Honda'},
{'capacity': 2300, 'id': 3, 'name': 'Austin Kiddie Limits'},
{'capacity': 2000, 'id': 4, 'name': 'Austin Ventures'}]
i get the unique keys with :
b= list({k for d in venues for k in d.keys()})
which results in random order :
['name', 'capacity', 'id']
i would like to sort the unique key result in following manner :
sorted_keys = ['id','name','capacity']
how may i achieve this ?

In python tuples are sorted element-wise, so using a key function that produces tuple from your dictionaries should do the trick.
>>> sorted(venues, key=lambda row: (row['id'], row['name'], row['capacity']))
To be slightly more concise, you could use operator.itemgetter.
>>> from operator import itemgetter
>>> sorted(venues, key=itemgetter('id','name','capacity'))

You can use sort() function and its property key to introduce specific criteria when sorting your list:
venues =[{'capacity': 700, 'id': 1, 'name': 'AMD'},
{'capacity': 2000, 'id': 2, 'name': 'Honda'},
{'capacity': 2300, 'id': 3, 'name': 'Austin Kiddie Limits'},
{'capacity': 2000, 'id': 4, 'name': 'Austin Ventures'}]
venues.sort(key=lambda x: x["capacity"])
print(venues)
Output: In this case it sorts by capacity parameter
[{'capacity': 700, 'id': 1, 'name': 'AMD'}, {'capacity': 2000, 'id': 2, 'name': 'Honda'}, {'capacity': 2000, 'id': 4, 'name': 'Austin Ventures'}, {'capacity': 2300, 'id': 3, 'name': 'Austin Kiddie Limits'}]
Also, you can sort unique keys as follows:
venues =[{'capacity': 700, 'id': 1, 'name': 'AMD'},
{'capacity': 2000, 'id': 2, 'name': 'Honda'},
{'capacity': 2300, 'id': 3, 'name': 'Austin Kiddie Limits'},
{'capacity': 2000, 'id': 4, 'name': 'Austin Ventures'}]
venues.sort(key=lambda x: (x["id"], x["name"], x["capacity"]))
print(venues)

To get your sort order you could use name length as the key.
b = sorted(b, key=lambda x: len(x))

Related

How to sort a List in Python on variable number of parameters [duplicate]

This question already has answers here:
How to sort objects by multiple keys?
(8 answers)
Closed 2 months ago.
I have a list of dictionaries, that I have to sort. However, the key/parameter on which to sort will be determined dynamically. The way this is done is I will create a method which will take the list and sorting columns as input as follows:
def processList(l, sortId= None):
<logic>
return l
Here's an example:
I have 5 dictionaries in a list:
[
{'name': 'alpha', 'price': 200, 'date': '2022-02-01'},
{'name': 'beta', 'price': 400, 'date': '2022-03-01'},
{'name': 'delta', 'price': 500, 'date': '2022-05-01'},
{'name': 'zeta', 'price': 400, 'date': '2022-02-10'},
{'name': 'kappa', 'price': 500, 'date': '2022-01-31'}
]
Now, I wish to sort it, but sorting criteria can be determined at runtime. So I can have sorting done by name and the output will be:
>>> l.sort(key=lambda x:x['name'])
[
{'name': 'alpha', 'price': 200, 'date': '2022-02-01'},
{'name': 'beta', 'price': 400, 'date': '2022-03-01'},
{'name': 'delta', 'price': 500, 'date': '2022-05-01'},
{'name': 'kappa', 'price': 500, 'date': '2022-01-31'},
{'name': 'zeta', 'price': 400, 'date': '2022-02-10'}
]
or sort by price and date:
>>> l.sort(key=lambda x:(x['price'], x['date']))
[
{'name': 'alpha', 'price': 200, 'date': '2022-02-01'},
{'name': 'zeta', 'price': 400, 'date': '2022-02-10'},
{'name': 'beta', 'price': 400, 'date': '2022-03-01'},
{'name': 'kappa', 'price': 500, 'date': '2022-01-31'},
{'name': 'delta', 'price': 500, 'date': '2022-05-01'}
]
I can't loop in over all the sorting columns because in the next iteration, it will rearrange/sort the data with respect to that column.
Is there a way to unpack the keys within lambda?
You can easily use custom list comprehension to write it like this:
l = sorted(l, key=lambda x: [ x[col] for col in sortId])

How to convert key to value in dictionary type?

I have a question about the convert key.
First, I have this type of word count in Data Frame.
[Example]
dict = {'forest': 10, 'station': 3, 'office': 7, 'park': 2}
I want to get this result.
[Result]
result = {'name': 'forest', 'value': 10,
'name': 'station', 'value': 3,
'name': 'office', 'value': 7,
'name': 'park', 'value': 2}
Please check this issue.
As Rakesh said:
dict cannot have duplicate keys
The closest way to achieve what you want is to build something like that
my_dict = {'forest': 10, 'station': 3, 'office': 7, 'park': 2}
result = list(map(lambda x: {'name': x[0], 'value': x[1]}, my_dict.items()))
You will get
result = [
{'name': 'forest', 'value': 10},
{'name': 'station', 'value': 3},
{'name': 'office', 'value': 7},
{'name': 'park', 'value': 2},
]
As Rakesh said, You can't have duplicate values in the dictionary
You can simply try this.
dict = {'forest': 10, 'station': 3, 'office': 7, 'park': 2}
result = {}
count = 0;
for key in dict:
result[count] = {'name':key, 'value': dict[key]}
count = count + 1;
print(result)

keep duplicates by key in a list of dictionaries

I have a list of dictionaries, and I would like to obtain those that have the same value in a key:
my_list_of_dicts = [{
'id': 3,
'name': 'John'
},{
'id': 5,
'name': 'Peter'
},{
'id': 2,
'name': 'Peter'
},{
'id': 6,
'name': 'Mariah'
},{
'id': 7,
'name': 'John'
},{
'id': 1,
'name': 'Louis'
}
]
I want to keep those items that have the same 'name', so, I would like to obtain something like:
duplicates: [{
'id': 3,
'name': 'John'
},{
'id': 5,
'name': 'Peter'
},{
'id': 2,
'name': 'Peter'
}, {
'id': 7,
'name': 'John'
}
]
I'm trying (not successfully):
duplicates = [item for item in my_list_of_dicts if len(my_list_of_dicts.get('name', None)) > 1]
I have clear my problem with this code, but not able to do the right sentence
Another concise way using collections.Counter:
from collections import Counter
my_list_of_dicts = [{
'id': 3,
'name': 'John'
},{
'id': 5,
'name': 'Peter'
},{
'id': 2,
'name': 'Peter'
},{
'id': 6,
'name': 'Mariah'
},{
'id': 7,
'name': 'John'
},{
'id': 1,
'name': 'Louis'
}
]
c = Counter(x['name'] for x in my_list_of_dicts)
duplicates = [x for x in my_list_of_dicts if c[x['name']] > 1]
You could use the following list comprehension:
>>> [d for d in my_list_of_dicts if len([e for e in my_list_of_dicts if e['name'] == d['name']]) > 1]
[{'id': 3, 'name': 'John'},
{'id': 5, 'name': 'Peter'},
{'id': 2, 'name': 'Peter'},
{'id': 7, 'name': 'John'}]
my_list_of_dicts = [{
'id': 3,
'name': 'John'
},{
'id': 5,
'name': 'Peter'
},{
'id': 2,
'name': 'Peter'
},{
'id': 6,
'name': 'Mariah'
},{
'id': 7,
'name': 'John'
},{
'id': 1,
'name': 'Louis'
}
]
df = pd.DataFrame(my_list_of_dicts)
df[df.name.isin(df[df.name.duplicated()]['name'])].to_json(orient='records')
Attempt similar to #cucuru
Hopefully Helpful.
Explained in comments what I did differently.
my_list_of_dicts = [{
'id': 3,
'name': 'John'
},{
'id': 5,
'name': 'Peter'
},{
'id': 2,
'name': 'Peter'
},{
'id': 6,
'name': 'Mariah'
},{
'id': 7,
'name': 'John'
},{
'id': 1,
'name': 'Louis'
}
]
# Create a list of names
names = [person.get('name') for person in my_list_of_dicts]
# Add item to list if the name occurs more than once in names
duplicates = [item for item in my_list_of_dicts if names.count(item.get('name')) > 1]
print(duplicates)
produces
[{'id': 3, 'name': 'John'}, {'id': 5, 'name': 'Peter'}, {'id': 2, 'name': 'Peter'}, {'id': 7, 'name': 'John'}]
[Program finished]

splitting nested dictionaries in python

I have a simple thing but for some reason my mind is blocked now
what is the name of this type of data
[{'self': 'test', 'id': 4, 'name': 'IT Network Support'}, {'self': 'tes_1', 'id': 5, 'name': 'IT PC Support'}]
how to split them into 2 dictionaries
it can be also dynamic and change to
[{'self': 'test', 'id': 4, 'name': 'IT Network Support'}, {'self': 'tes_1', 'id': 5, 'name': 'IT PC Support'} ,{'self': 'tes_2', 'id': 6, 'name': 'IT Voice Support'} ]
I want a solution which can be dynamic
Easiest way would be:
dict1, dict2 = [{'self': 'test', 'id': 4, 'name': 'IT Network Support'}, {'self': 'tes_1', 'id': 5, 'name': 'IT PC Support'}]
Which unpacks them into the variable dict1 and dict2
You can also just index into the list directly e.g.
dict_list = [{'self': 'test', 'id': 4, 'name': 'IT Network Support'}, {'self': 'tes_1', 'id': 5, 'name': 'IT PC Support'}]
dict1 = dict_list[0]
dict2 = dict_list[1]
You can unpack iterables in python!
a, b = [{'self': 'test', 'id': 4, 'name': 'IT Network Support'}, {'self': 'tes_1', 'id': 5, 'name': 'IT PC Support'}]

Check unique values for a key in a list of dicts [duplicate]

This question already has answers here:
Remove duplicate dict in list in Python
(16 answers)
Closed 6 years ago.
I have a list of dictionaries where I want to drop any dictionaries that repeat their id key. What's the best way to do this e.g:
example dict:
product_1={ 'id': 1234, 'price': 234}
List_of_products[product1:, product2,...........]
How can I the list of products so I have non repeating products based on their product['id']
Select one of product dictionaries in which the values with the same id are different. Use itertools.groupby,
import itertools
list_products= [{'id': 12, 'price': 234},
{'id': 34, 'price': 456},
{'id': 12, 'price': 456},
{'id': 34, 'price': 78}]
list_dicts = list()
for name, group in itertools.groupby(sorted(list_products, key=lambda d : d['id']), key=lambda d : d['id']):
list_dicts.append(next(group))
print(list_dicts)
# Output
[{'price': 234, 'id': 12}, {'price': 456, 'id': 34}]
If the product dictionaries with the same id are totally the same, there is an easier way as described in Remove duplicate dict in list in Python. Here is a MWE.
list_products= [{'id': 12, 'price': 234},
{'id': 34, 'price': 456},
{'id': 12, 'price': 234},
{'id': 34, 'price': 456}]
result = [dict(t) for t in set([tuple(d.items()) for d in list_products])]
print(result)
# Output
[{'price': 456, 'id': 34}, {'price': 234, 'id': 12}]
a = [{'id': 124, 'price': 234}, {'id': 125, 'price': 234}, {'id': 1234, 'price': 234}, {'id': 1234, 'price': 234}]
a.sort()
for indx, val in enumerate(a):
if val['id'] == a[indx+1]['id']:
del a[indx]

Categories