In-place way to apply a permutation to a list? (inverse of sorting-by-key)

后端 未结 7 615
心在旅途
心在旅途 2021-01-02 05:06

Here\'s a example of what I want to do

spam_list = [\"We\", \"are\", \"the\", \"knights\", \"who\", \"say\", \"Ni\"]
spam_order = [0,1,2,4,5,6,3]
spam_list.m         


        
相关标签:
7条回答
  • If the issue is specifically in-placeness and not memory usage per se -- if you want this to have side effects, in other words -- then you could use slice assignment. Stealing from Peter Collingridge:

    other_spam_list = spam_list
    spam_list[:] = [spam_list[i] for i in spam_order]
    assert other_spam_list == spam_list
    

    It seems you might even be able to do this with a generator expression! But I suspect this still implicitly creates a new sequence of some sort -- probably a tuple. If it didn't, I think it would exhibit wrong behavior; but I tested it, and its behavior seemed correct.

    spam_list[:] = (spam_list[i] for i in spam_order)
    

    Aha! See this excellent answer by the inimitable Sven Marnach -- generator slice assignment does indeed generate an implicit tuple. Which means it's safe, but not as memory efficient as you might think. Still, tuples are more memory efficient than lists, so the generator expression is preferable from that perspective.

    0 讨论(0)
提交回复
热议问题