1

I am trying to use one list to sort another and keep them synchronized at the same time:

keys = [x,x,x,y,y,x,x,z,z,z,x,x]
data = [1,2,3,4,5,6,7,8,9,10,11,12]

I want to use the keys list to organize the data list into subgroups of the same keys.

result = [[1,2,3,6,7,11,12],[4,5,],[8,9,10]]

I also want to make sure that the list is sorted within each subgroup.

so far i was able to get it all sorted properly:

group = []

data = sorted(zip(data, keys), key=lambda x: (x[1]))
for i, grp in groupby(data, lambda x: x[1]):
    sub_group = [], []
    for j in grp:
        sub_group.append(j[1])
    group.extend(sub_group)

What else am I missing? Thanks!

3
  • Is what you have working? If not, what is wrong with it? Commented Jul 10, 2014 at 1:32
  • well it returns a sorted but flat list instead of list of lists...i want something like "result" list that i mentioned Commented Jul 10, 2014 at 1:33
  • I would have thought that a dict or an OrderedDict would be a more useful output, e.g. something like {'x': [1, 2, 3, 6, 7, 11, 12], 'y': [4, 5], 'z': [8, 9, 10]}. Commented Jul 10, 2014 at 1:35

4 Answers 4

2

It would much simpler if you used collections.OrderedDict and its setdefault method:

from collections import OrderedDict

# To demonstrate, I made the keys into strings
keys = ['x', 'x', 'x', 'y', 'y', 'x', 'x', 'z', 'z', 'z', 'x', 'x']
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

dct = OrderedDict()
for key,val in zip(keys, data):
    dct.setdefault(key, []).append(val)

print(dct)
print(list(dct.values()))

Output:

OrderedDict([('x', [1, 2, 3, 6, 7, 11, 12]), ('y', [4, 5]), ('z', [8, 9, 10])])
[[1, 2, 3, 6, 7, 11, 12], [4, 5], [8, 9, 10]]
Sign up to request clarification or add additional context in comments.

Comments

2

You have almost done. Try this code

group = []
data = sorted(zip(data, keys), key=lambda x: (x[1]))
for i, grp in groupby(data, lambda x: x[1]):
    group.append([item[0] for item in grp])

grp has (data, key) pair, so you need to select data from the pair as [item[0] for item in grp]

UPDATED

This code I used for answer.

from itertools import groupby

x, y, z = range(3)
keys = [x,x,x,y,y,x,x,z,z,z,x,x]
data = [1,2,3,4,5,6,7,8,9,10,11,12]

group = []
data = sorted(zip(data, keys), key=lambda x: (x[1]))
for i, grp in groupby(data, lambda x: x[1]):
    group.append([item[0] for item in grp])

print group

6 Comments

Your welcome. BTW, did you define x, y, and z as x, y, z = range(3)?
no i havent. why would i want to do that? to ensure proper sorting?
Never mind, I just want know what x, y, and z in the list because they are some variables.
yeah they could be either numbers that i use to group similar objects by or strings...either way they are sort-able.
There seems to be one problem with this code. Last line of code group.append([item[0] for item in grp]) creates a list that at first subgroup has all of the items originally passed to it. After that the following subgroups are the proper splits grouped together by the key. Ideas?
|
1

OrderedDict may well be a better option but ....

import itertools as it
from operator import itemgetter
x = 1
y = 2
z = 3
keys = [x,x,x,y,y,x,x,z,z,z,x,x]
data = [1,2,3,4,5,6,7,8,9,10,11,12]
key = itemgetter(1)
value = itemgetter(0)

data = sorted(zip(data, keys), key=key)
print [map(value, grp) for k, grp in it.groupby(data, key)]

Comments

0

Beware that OrderedDict orders the keys by their insertion order, and not as if the keys were sorted after the fact. If the 'keys' list were not in the required order you would not get the intended result.

My solution:

from collections import defaultdict

keys = ['x', 'x', 'x', 'y', 'y', 'x', 'x', 'z', 'z', 'z', 'x', 'x']
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

# group 'data' values by 'key'
grouped = defaultdict(list)
for key, data in zip(keys, data):
    grouped[key].append(data)

# construct the final list of subgroups
# contents of each subgroup must be sorted
# also sorting the keys so that the 'x' subgroup comes before the 'y' subgroup etc
grouped_and_ordered = [sorted(grouped[key]) for key in sorted(grouped.keys())]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.