开发者

Python: Sort list using another list order, having different lengths, and without 'sorted'

I'll to explain this right:

I'm in an environment where I can't use python built-in functions (like 'sorted', 'set'), can't declare methods, can't make conditions (if), and can't make loops, except for:

  • can call methods (but just one each time, and saving returns on another variable

    foo python:item.sort(); #foo variable takes the value that item.sort() returns

    bar python:foo.index(x);

  • and can do list comprehension

    [item['bla'] for item in foo]

...what I don't think that will help on this question

I have a 'correct_order' list, with this values:

correct_order = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

and I have a 'messed_order' list, with this values:

messed_order = [55, 1, 44, 3, 66, 5, 4, 7, 2, 9, 0, 10, 6, 8]

Well, I have to reorder the 'messed_order' list, using the index of 'correct_order' as base. The order of the rest of items not included in correct_order doesn't matter.

Something like th开发者_如何学Gois would solve (again, except that I can't use loops):

for item in correct_order:
    messed_order[messed_order.index(item)], messed_order[correct_order.index(item)] = messed_order[correct_order.index(item)], messed_order[messed_order.index(item)]

And would result on the 'ordered_list' that I want:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 55, 66, 44]

So, how can I do this?

For those who know zope/plone, I'm on a skin page (.pt), that doesn't have a helper python script (what I think that is not possible for skin pages, only for browser pages. If it is, show me how and I'll do it).


It's hard to answer, not knowing exactly what's allowed and what's not. But how about this O(N^2) solution?

[x for x in correct_order if x in messed_order] + [x for x in messed_order if x not in correct_order]


Create a Script (Python) object in your skin and use that as a function. TALES expressions are limited for a reason: they are there only to help you create HTML or XML markup, not do full-scale business logic. Better still, create a proper browser view and avoid the severe restrictions laid on Through-The-Web editable code.

Also, you are misrepresenting or misunderstanding TALES. You can use builtin methods like sorted and set. And instead of if you can use test(condition, iftrue, iffalse) or a good old condition and iftrue or iffalse with the limitation that the result of iftrue must itself evaluate to true.

Even better, you can access a limited set of Python modules via the modules dictionary, such as modules['string']. You'll need to make additional security declarations in a filesystem python module to extend this though.

See the Python TALES expression section of the TAL documentation. Note that the list of built-ins accessible to TALES listed there has since been expanded to cover newer python versions.


Does the exact order of the 55/66/44 items matter, or do they just need to be listed at the end? If the order doesn't matter you could do this:

[i for i in correct_order if i in messed_order] +
    list(set(messed_order) - set(correct_order))


Here is one that destroys messed_order

[messed_order.remove(i) or i for i in correct_order if i in messed_order] + messed_order

This one sorts messed_order in place

messed_order.sort(key=(correct_order+messed_order).index)


Not to detract from the answers already given, but it's python - you aren't arbitrarily restricted from using loops:

for item in correct_order: messed_order[messed_order.index(item)], messed_order[correct_order.index(item)] = messed_order[correct_order.index(item)], messed_order[messed_order.index(item)]

is as valid as putting the loop on two lines.

Alternatively, this is Zope - if you can't do it in a single "python:" expression, yes you can use a helper script. Scripts are found by acquisition, so a template containing something like:

<tag tal:define="abc context/script">

will lookup a either an attribute 'script' of the current object (context) [which could be a method or a property], or a "Script (Python)" object named script in the current folder, or in any ancestor folder! In fact, it doesn't even need to be a script object - though for your purpose it needs to be some object that returns a list.

Far from "the Department of Arbitrary Restrictions" as Thanatos put it, it's more as if there aren't enough restrictions!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜