0

I want to get a ordered list with ascending order, but leave out the first element in the original list. But the first for-loop only runs 4 times. After 4 times loop in first for-loop:

lst=[6, 5, 4]

I think the first for-loop should keep running, but it finishes. I don't know why?

Source code below:

#coding: utf-8
lst = [0, 1, 6, 2, 5, 3, 4]
new_lst = []  # the ordered list, [0, 1, 2, 3, 4, 5, 6]
p0 = lst[0]  # the first element can be arbitrary
lst.remove(p0)
new_lst.append(p0)
for temp in lst:
    lst.remove(temp)
    while 1:
        for pt in lst:
            if temp < pt:
                continue
            else:
                lst.append(temp)
                temp = pt
                lst.remove(pt)
                break
        else:
            new_lst.append(temp)
            break

print("the ordered list:", new_lst)

At last, I only get:

('the ordered list:', [0, 1, 2, 3])
Dlamini
  • 285
  • 1
  • 9
  • 1
    Welcome to StackOverflow. Please read and follow the posting guidelines in the help documentation. [Minimal, complete, verifiable example](http://stackoverflow.com/help/mcve) applies here. We cannot effectively help you until you post your MCVE code and accurately describe the problem. We should be able to paste your posted code into a text file and reproduce the problem you described. "cannot be accomplished correctly" is not a problem specification. – Prune Jan 24 '18 at 01:28
  • 1
    What is your desired result, `[1, 2, 3, 4, 5, 6]`? – John Kugelman Jan 24 '18 at 01:30
  • @JohnKugelman, Judging by his code, I'd assume so – Michael Ilie Jan 24 '18 at 01:30
  • Can you just use `sorted`? A lot simpler that way (`new_lst = sorted(lst[1:])` could replace it all). Either way, [you can't safely mutate a `list` while iterating it.](https://stackoverflow.com/q/1207406/364696) – ShadowRanger Jan 24 '18 at 01:31
  • Isn't there also `list.sort()`? My point is that the User is clearly un aware of more efficient solutions. OR this could be a possible HomeWork Question – Michael Ilie Jan 24 '18 at 01:33
  • Yes, my desired result should be [0, 1, 2, 3, 4, 5, 6]. I cannot use sorted() function, because in my original program the elements of lst are many instances of self-defining class. So I cannot use sorted(). – fanronghong Jan 24 '18 at 01:34
  • @fanronghong: You said you wanted to "leave out the first element in the original list", so wouldn't that imply you want `[1, 2, 3, 4, 5, 6]`, not `[0, 1, 2, 3, 4, 5, 6]`? – ShadowRanger Jan 24 '18 at 01:36
  • And what do you want the input to be: `[6,5,4]`? do you want python to generate all the number from 1... 4? please be speceific – Michael Ilie Jan 24 '18 at 01:36
  • @fanronghong: You can still use `sorted`, you just need to define the `__lt__` special method, or provide a `key` function that takes an instance of your class and returns the derived value to sort on. This sounds like [an XY problem](https://meta.stackexchange.com/q/66377/322040); you don't know how to use `list.sort`/`sorted` properly or with custom objects, so you invent an unnecessary and overly complex custom sort routine. – ShadowRanger Jan 24 '18 at 01:38
  • @ShadowRanger: A sequence just can be sorted by size if you use sorted(). But my desire is sorted by right-hand rule. So I just cannot use sorted(). Actually, I thought about sorted() before. – fanronghong Jan 24 '18 at 01:46
  • @fanronghong: You can sort by a lot more than just size with a `key` function. If you have a more complicated comparison, than can only be done if you have both objects available to perform it, not a simple derivation from each object in isolation, you can write a custom comparison function and pass it as the `cmp` argument (on Py2) or as the `key` argument after [wrapping in `functools.cmp_to_key`](https://docs.python.org/3/library/functools.html#functools.cmp_to_key) (on Py3). You should not need to write a custom sorting algorithm. I suggest you ask a new question with your real problem. – ShadowRanger Jan 24 '18 at 01:51
  • @ShadowRanger: Thanks a lot. Sounds great! I should try it. Thanks all again for your time and patience. Additionally, I really want to know why this happened. It looks strange, but interesting. – fanronghong Jan 24 '18 at 01:55
  • 1
    @fanronghong: As I stated before, the "why" is that [it's not safe to mutate a `list` while iterating it](https://stackoverflow.com/q/1207406/364696); in practice on CPython, it doesn't error out, but if you remove the item you're currently on, it ends up skipping the following item in the iteration. Click the link in this comment, and view the other linked questions from there; several of them are of the form "I call `list.remove` in a loop that iterates over the `list` and it breaks, why?" – ShadowRanger Jan 24 '18 at 02:01
  • In particular, look at [this answer](https://stackoverflow.com/a/34238688/364696). – ShadowRanger Jan 24 '18 at 02:04
  • @ShadowRanger: I got it. Thanks. In future I must be careful about this. And I should be better not use this one. Thanks a lot!!! – fanronghong Jan 24 '18 at 02:04
  • You should upvote/accept an answer: https://stackoverflow.com/help/someone-answers – rnso Jan 24 '18 at 08:10

3 Answers3

1

To ignore first element in sorting:

newlst = [lst[0]]+sorted(lst[1:])

First element lst[0] has to be enclosed in [ ] to get a list which can be extended using + with rest of the list (lst[1:]).

rnso
  • 23,686
  • 25
  • 112
  • 234
0

try new_lst = sorted(lst). This sorts a list by integer value (and ascii value if characters are present). This is a much nicer solution for your problem and is way more pythonic.

Michael Ilie
  • 449
  • 2
  • 16
0

If you can use sorted, that's the easiest way to do it. If not, this is my solution:

lst = [0, 1, 6, 2, 5, 3, 4]
new = lst[1:]
for num in range(len(new)-1, 0, -1):
    for i in range(num):
        if new[i] > new[i+1]:
            new[i], new[i+1] = new[i+1], new[i]
new.insert(0, lst[0])
print(new) 
kaifi
  • 126
  • 1
  • 8