Sort a list using another list

93 views
Skip to first unread message

Aren Voorhees

unread,
Aug 18, 2016, 12:02:02 AM8/18/16
to Python Programming for Autodesk Maya
I realized that subject doesn't sound like it makes any sense - but here is what I'm trying to do: I am generating two lists...one looks something like this - 

[MeshUV(u'pCubeShape1.map[0]'), MeshUV(u'pCubeShape1.map[1]'), MeshUV(u'pCubeShape1.map[2]'), MeshUV(u'pCubeShape1.map[3]'), MeshUV(u'pCubeShape1.map[4]'), MeshUV(u'pCubeShape1.map[5]'),

MeshUV(u'pCubeShape1.map[6]'), MeshUV(u'pCubeShape1.map[7]'), MeshUV(u'pCubeShape1.map[8]'), MeshUV(u'pCubeShape1.map[9]'), MeshUV(u'pCubeShape1.map[10]'), MeshUV(u'pCubeShape1.map[11]'),

MeshUV(u'pCubeShape1.map[12]'), MeshUV(u'pCubeShape1.map[13]'), MeshUV(u'pCubeShape1.map[14]'), MeshUV(u'pCubeShape1.map[15]')]


The other is something like this: [0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1]


The two lists correspond to each other, so I'd like to sort the elements in the first list by the matching integer in the 2nd list.  In this example there would only be two resulting lists of uvs, but ultimately there could be any number of resulting lists.


BTW, the point of this is to sort the uvs of a given mesh into their different shells so I can perform an operation on all the shells of a mesh.  


Thanks!

Aren 

Christopher Crouzet

unread,
Aug 18, 2016, 12:34:32 AM8/18/16
to python_in...@googlegroups.com
If I'm understanding it right, try this:

import itertools

def sort_uvs_by_shells(uvs, shells):
    groups = itertools.groupby(sorted(zip(shells, uvs)), key=lambda x: x[0])
    return ((group[0], [x[1] for x in group[1]]) for group in groups)
    # dictionary version:
    # return {group[0]: [x[1] for x in group[1]] for group in groups}

uvs = list(range(16))
shells = [0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1]
result = sort_uvs_by_shells(uvs, shells)
for shell, uvs in result:
# dictionary version:
# for shell, uvs in result.iteritems():
    print("uvs for shell %d: %s" % (shell, uvs))


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/f2705166-dc4d-47b9-a3f0-4272923fc084%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

Justin Israel

unread,
Aug 18, 2016, 12:40:26 AM8/18/16
to python_in...@googlegroups.com
On Thu, Aug 18, 2016 at 4:34 PM Christopher Crouzet <christoph...@gmail.com> wrote:
If I'm understanding it right, try this:

import itertools

def sort_uvs_by_shells(uvs, shells):
    groups = itertools.groupby(sorted(zip(shells, uvs)), key=lambda x: x[0])
    return ((group[0], [x[1] for x in group[1]]) for group in groups)
    # dictionary version:
    # return {group[0]: [x[1] for x in group[1]] for group in groups}

uvs = list(range(16))
shells = [0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1]
result = sort_uvs_by_shells(uvs, shells)
for shell, uvs in result:
# dictionary version:
# for shell, uvs in result.iteritems():
    print("uvs for shell %d: %s" % (shell, uvs))

Nice example. Could this even be shortened to something like this? (I have simplified the data for example purposes)

from itertools import izip

l1 = ['a', 'b', 'c']
l2 = [3, 2 ,1]

print [i[1] for i in sorted(izip(l2, l1))]
# ['c', 'b', 'a']

Justin



On 18 August 2016 at 11:02, Aren Voorhees <are...@gmail.com> wrote:
I realized that subject doesn't sound like it makes any sense - but here is what I'm trying to do: I am generating two lists...one looks something like this - 

[MeshUV(u'pCubeShape1.map[0]'), MeshUV(u'pCubeShape1.map[1]'), MeshUV(u'pCubeShape1.map[2]'), MeshUV(u'pCubeShape1.map[3]'), MeshUV(u'pCubeShape1.map[4]'), MeshUV(u'pCubeShape1.map[5]'),

MeshUV(u'pCubeShape1.map[6]'), MeshUV(u'pCubeShape1.map[7]'), MeshUV(u'pCubeShape1.map[8]'), MeshUV(u'pCubeShape1.map[9]'), MeshUV(u'pCubeShape1.map[10]'), MeshUV(u'pCubeShape1.map[11]'),

MeshUV(u'pCubeShape1.map[12]'), MeshUV(u'pCubeShape1.map[13]'), MeshUV(u'pCubeShape1.map[14]'), MeshUV(u'pCubeShape1.map[15]')]


The other is something like this: [0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1]


The two lists correspond to each other, so I'd like to sort the elements in the first list by the matching integer in the 2nd list.  In this example there would only be two resulting lists of uvs, but ultimately there could be any number of resulting lists.


BTW, the point of this is to sort the uvs of a given mesh into their different shells so I can perform an operation on all the shells of a mesh.  


Thanks!

Aren 

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
--

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CANuKW51A%3D%3DaeKRa%2B9-nG%3Dwc8FrhgcccX-Rxf8YSKSnm-Lmvbdw%40mail.gmail.com.

Justin Israel

unread,
Aug 18, 2016, 12:41:48 AM8/18/16
to python_in...@googlegroups.com
On Thu, Aug 18, 2016 at 4:40 PM Justin Israel <justin...@gmail.com> wrote:
On Thu, Aug 18, 2016 at 4:34 PM Christopher Crouzet <christoph...@gmail.com> wrote:
If I'm understanding it right, try this:

import itertools

def sort_uvs_by_shells(uvs, shells):
    groups = itertools.groupby(sorted(zip(shells, uvs)), key=lambda x: x[0])
    return ((group[0], [x[1] for x in group[1]]) for group in groups)
    # dictionary version:
    # return {group[0]: [x[1] for x in group[1]] for group in groups}

uvs = list(range(16))
shells = [0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1]
result = sort_uvs_by_shells(uvs, shells)
for shell, uvs in result:
# dictionary version:
# for shell, uvs in result.iteritems():
    print("uvs for shell %d: %s" % (shell, uvs))

Nice example. Could this even be shortened to something like this? (I have simplified the data for example purposes)

from itertools import izip

l1 = ['a', 'b', 'c']
l2 = [3, 2 ,1]

print [i[1] for i in sorted(izip(l2, l1))]
# ['c', 'b', 'a']


Correction: Forget the use of itertool.izip. It is not necc here.

[i[1] for i in sorted(zip(l2, l1))]

Christopher Crouzet

unread,
Aug 18, 2016, 12:51:25 AM8/18/16
to python_in...@googlegroups.com
Aren asked for “any number of resulting lists”, which I interpreted as him wanting one list of UVs per shell, whereas the sorted zip version returns a single list of ordered UVs with no way to figure out from which shell they belong to. But that wouldn't be the first time that I misunderstand something! :)



 
Justin



To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.
--

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAPGFgA0hA8TwVZ7n%3DxFH%3D-kVmE-_-ucngSgTpEC7dxmWHA5ogA%40mail.gmail.com.

For more options, visit https://groups.google.com/d/optout.

Justin Israel

unread,
Aug 18, 2016, 1:02:25 AM8/18/16
to python_in...@googlegroups.com
On Thu, Aug 18, 2016 at 4:51 PM Christopher Crouzet <christoph...@gmail.com> wrote:
Aren asked for “any number of resulting lists”, which I interpreted as him wanting one list of UVs per shell, whereas the sorted zip version returns a single list of ordered UVs with no way to figure out from which shell they belong to. But that wouldn't be the first time that I misunderstand something! :)

No I see what you mean. There was that extra sentence that I didn't read which explained that. I only saw it as sorting one list by another list :-)
 

 
Justin



To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
--

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CANuKW52wkVhc78BDLWuTq06e%2B--iLVpHN0gs%2BjAa4wxZ7zwKMA%40mail.gmail.com.

Aren Voorhees

unread,
Aug 21, 2016, 11:45:16 PM8/21/16
to python_in...@googlegroups.com
Thanks to both of you for your rapid responses!  Using Christopher's example I was able to get it working to where it could sort the uvs by their shell (I must confess I don't exactly understand how the sort_uvs_by_shells function works, but I'll study up on it and get it figured out in my head).  Thanks again, this will allow me to finally finish up this tool I've been trying to work on!


 
Justin



To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.
--

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

--
You received this message because you are subscribed to a topic in the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/python_inside_maya/l_yplAm5OuA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to python_inside_maya+unsub...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAPGFgA2y6qM7poUoU4qQo5xQteofOwLEONoxrKZnFa02rrcp6w%40mail.gmail.com.

Christopher Crouzet

unread,
Aug 22, 2016, 12:42:50 AM8/22/16
to python_in...@googlegroups.com
Glad to hear that it's working out for you!

And don't worry for not understanding how the `sort_uvs_by_shells` function works, it's my fault for writing it in a not so readable way.

I'll give a go at decomposing and describing each of its operations. It's a good exercise for me as I'm usually pretty bad at explaining things :)

    def sort_uvs_by_shells(uvs, shells):
        zipped = zip(shells, uvs)
        ordered = sorted(zipped)
        groupped = itertools.groupby(ordered, key=lambda x: x[0])
        return ((group[0], tuple(x[1] for x in group[1])) for group in groupped)



First, the `zip` function. It actually has a good fitting name—imagine two sequences of a same length, say `left = ['a', 'b', 'c']` and `right = [1, 2, 3]`. Calling `zip(left, right)` will return a new list, still of the same length, where each corresponding element from the left and right lists are joined together in a tuple. So the result here would be `[('a', 1), ('b', 2), ('c', 3)]`.

In our case, we use `zip` to group each UV to its shell, and the result we get form the zip is something following the idea of `[('shell_0', 'uv_1'), ('shell_0', 'uv_2'), ('shell_1', 'uv_4'), ('shell_0', 'uv_5'), ...]`.

With this being done, we can now keep moving on grouping together all the UVs for a same shell. There's another neat function to do just this: `itertools.groupby`. If we were to do it on a list such as `['a', 'a', 'a', 'a', 'b', 'b', 'a', 'a', 'a']`, then it would return an iterator of tuples where the first tuple would represent the first 4 letters 'a', the second tuple the 2 following letters 'b', and finally the last tuple the last 3 letters 'a'. So it only groups elements which are contiguous in the list, and it happens that our shell/uvs list is not in an ideal state for such a grouping (in the example above, we've got 2 'shell_0', then 1 'shell_1', then another 'shell_0').

That's why we need to order first the result of the zip operation so all the shell/uvs pairs which belong to the same shell are listed next to each other. The built-in `sorted` function does just that. The sorting works by comparing corresponding values of each tuple, starting by the first one. For example `(4, 3) > (3, 5)` so `(3, 5)` will be end up being before `(4, 3)`. In other words, putting the shells and uvs items in this order when doing the zip operation made it easy for us here. Otherwise we could still have used either the `cmp` or the `key` parameters from the `sorted` function.

Now the `ordered` list is ready to be grouped. The second parameter of the `itertools.groupby` function is being passed a lambda (an anonymous function) to tell the function which element from our shell/uvs pair should be used for the grouping—that's the shell item, which is index 0.

And finally, what's left is to output the result after extracting the data from the `itertools.groupby` function.



 
Justin



To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsubscribe@googlegroups.com.
--

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsubscribe@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsubscribe@googlegroups.com.

--
You received this message because you are subscribed to a topic in the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/python_inside_maya/l_yplAm5OuA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to python_inside_maya+unsubscribe@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Aren Voorhees

unread,
Aug 24, 2016, 12:17:52 AM8/24/16
to Python Programming for Autodesk Maya
I'd call that a pretty good explanation actually!  Thanks for taking the time to go through that all - makes much more sense now!  I'll see if I can wrap things up and post the final version so you can see what the point of the whole thing is.
Reply all
Reply to author
Forward
0 new messages