Grouping Elements of a List based on attributes of the elements
I have the following list
List=[
('G1', 'CFS', 'FCL', 'R1'),
('G3', 'LOOSEFREIGHT', 'MIXEDLCL', 'R9'),
('G4', 'CFS', 'FCL', 'R10'),
('G2', 'LOOSEFREIGHT', 'LCL', 'R4'),
('G1', 'CFS', 'FCL', 'R2'),
('G2', 'LOOSEFREIGHT', 'LCL', 'R5'),
]
Now I want to group this elements of List first by index [1] (i.e. CFS and LOOSEFREIGHT) together and for those elements which are grouped together for LOOSEFREIGHT, I want to further divide them into different groups based on index[2] (i.e. LCL or MIXEDLCL).
So essentially I want them grouped into different lists and my solution should be of the form
New_List=[
[
('G1', 'CFS', 'FCL', 'R1'),
('G1', 'CFS', 'FCL', 'R2'),
('G4', 'CFS', 'FCL', 'R10')
],
[
('G2', 'LOOSEFREIGHT', 'LCL', 'R4'),
('G2', 'LOOSEFREIGHT', 'LCL', 'R5')
开发者_JS百科 ],
[
('G3', 'LOOSEFREIGHT', 'MIXEDLCL', 'R9')
],
]
How do I do it?
I managed to do divide them into different lists based on index [1] however I was not able to further divide them based on index [2]
Any help is appreciated.
If this is a one-off task list-comprehensions are probably the simplest solution:
>>> new_list = []
>>> new_list.append([i for i in L if i[1] == 'CFS']) # where L is your original list
>>> new_list.append([i for i in L if i[1] == 'LOOSEFREIGHT' and i[2] == 'LCL'])
>>> new_list.append([i for i in L if i[1] == 'LOOSEFREIGHT' and i[2] == 'MIXEDLCL'])
>>> from pprint import pprint as pp
>>> pp(new_list)
[[('G1', 'CFS', 'FCL', 'R1'),
('G4', 'CFS', 'FCL', 'R10'),
('G1', 'CFS', 'FCL', 'R2')],
[('G2', 'LOOSEFREIGHT', 'LCL', 'R4'), ('G2', 'LOOSEFREIGHT', 'LCL', 'R5')],
[('G3', 'LOOSEFREIGHT', 'MIXEDLCL', 'R9')]]
If you need an example for the more general case—where you don't necessarily know in advance the number of possible groups—you can use itertools.groupby something like this:
import itertools as it
import operator as op
new_list = []
for k,g in it.groupby(sorted(L, key=op.itemgetter(1,2)), key=op.itemgetter(1,2)):
new_list.append(list(g))
pp(new_list)
Results:
[[('G1', 'CFS', 'FCL', 'R1'),
('G4', 'CFS', 'FCL', 'R10'),
('G1', 'CFS', 'FCL', 'R2')],
[('G2', 'LOOSEFREIGHT', 'LCL', 'R4'), ('G2', 'LOOSEFREIGHT', 'LCL', 'R5')],
[('G3', 'LOOSEFREIGHT', 'MIXEDLCL', 'R9')]]
Here is an answer using a dict where the key is index[1] (ex- 'CFS'), and its value is another dict where its key is index[2] (ex- 'FCL'). This example creates the structure, then uses for loops to print out the sorted order that you desire. Its stronger than Adam's answer since his is specifically built for certain values:
sorted_values = []
d = {}
for entry in a:
d[entry[1]] = { entry[2]: entry }
for i in sorted(d):
for j in sorted(d[i]):
sorted_values.append(d[i][j])
Thus, when you print sorted_values, you get:
[[('G1', 'CFS', 'FCL', 'R1'), ('G4', 'CFS', 'FCL', 'R10'), ('G1', 'CFS', 'FCL', 'R2')], [('G2', 'LOOSEFREIGHT', 'LCL', 'R4'), ('G2', 'LOOSEFREIGHT', 'LCL', 'R5')]]
I would make a custom sort routine:
def custom_sort(data):
cfs = []
loose_lcl = []
loose_mixed = []
for row in data:
if row[1] == 'CFS':
cfs.append(row)
elif row[1] == 'LOOSEFREIGHT' and row[2] == 'LCL':
loose_lcl.append(row)
elif row[1] == 'LOOSEFREIGHT' and row[2] == 'MIXEDLCL':
loose_mixed.append(row)
else:
raise ValueError("Unknown data: %r" % (row,))
return [cfs, [loose_lcl, loose_mixed]]
精彩评论