简体   繁体   中英

Python list: how to make it ordered and get rid of duplicates

I'm a novice in Python and my homework is to take a list with a bunch of numbers in it and

  1. make the list ordered from lowest number to highest
  2. get rid of duplicate numbers.

This must be accomplished with loops

My code so far:

numbers = [84, 79, 66, 69, 79, 82, 78, 79, 84, 84, 79, 66, 69, 84,
           72, 65, 84, 73, 83, 84, 72, 69, 81, 85, 69, 83, 84, 73, 79, 78]
ordered = []
while numbers != []:
    min = numbers[0]
    for i in range(0, len(numbers)):
        if numbers[i] < min:
            min = numbers[i]
    ordered.append(min)
    j = 0
    while j < len(numbers):
        if numbers[j] == min:
            numbers.pop(j)
        j += 1
print(ordered)

And the output:

[65, 66, 69, 72, 73, 78, 79, 79, 81, 82, 83, 84, 84, 84, 85]

So task1 is okay but task2 is only accomplished at some points not all. I can't figure out why? Thank you in advance for any help! PS: I already solved the problem in another way but it just keeps bugging me why this posted idea of mine didn't work.

Others have provided shorter and more efficient ways of doing this, but you asked specifically what goes wrong with your approach. The problem is in this bit:

    j = 0
    while j < len(numbers):
        if numbers[j] == min:
            numbers.pop(j)
        j += 1

What happens if min occurs twice back to back? Let's say for example that min == 3 , and the list is [1, 3, 3, 7] .

  • For j == 0 , numbers[j] == 1 so we don't pop it, and increment j .
  • For j == 1 , numbers[j] == 3 so we remove the element 1 and increment j . The list is now [1, 3, 7] .
  • For j == 2 , numbers[j] == 7 so we don't pop it, and we're done.

Whoops! We have skipped over the second 3 because it moved back one position when we popped its predecessor, while j moved forwards one position at the same time.

The solution is to only increment j if we didn't remove anything, because we need to re-check the element at position j after we removed its predecessor:

    j = 0
    while j < len(numbers):
        if numbers[j] == min:
            numbers.pop(j)
        else:
            j += 1

Let's verify that the loop is still guaranteed to terminate. Each iteration, either j becomes larger, or len(numbers) becomes smaller, so eventually they will meet and j < len(numbers) becomes false. So we're good.

You can use bubble sort.(If you need another sorting method, just replace it)

numbers = [84, 79, 66, 69, 79, 82, 78, 79, 84, 84, 79, 66, 69, 84,
    72, 65, 84, 73, 83, 84, 72, 69, 81, 85, 69, 83, 84, 73, 79, 78]

def bubble_sort(arr):
    n = len(arr)
    for i in range(n-1):
        for j in range(0, n-i-1):
            if arr[j] > arr[j+1] :
                arr[j], arr[j+1] = arr[j+1], arr[j]
    no_dub = []
    for i in arr:
        if i not in no_dub:
            no_dub.append(i)
    return no_dub
bubble_sort(numbers)

The result:

[65, 66, 69, 72, 73, 78, 79, 81, 82, 83, 84, 85]

You need a small addition:

    while j < len(numbers):
    if numbers[j] == min:
        numbers.pop(j)
        j -= 1             #increment should not advance if you pop a number
    j += 1

Then it will work

set will remove duplicates

sorted will sort it

sorted(list(set([65, 66, 69, 72, 73, 78, 79, 79, 81, 82, 83, 84, 84, 84, 85])))
[65, 66, 69, 72, 73, 78, 79, 81, 82, 83, 84, 85]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM