странное поведение при удалении дубликатов в списке - PullRequest
3 голосов
/ 07 февраля 2012

У меня есть список целых чисел.

Я хотел бы отсортировать их и удалить все дубликаты.Я видел два разных решения в интернете.Оба, кажется, дают тот же самый результат, который я не ожидаю.

a = integer_combinations(5, 5)
print a
>>[4, 8, 16, 32, 9, 27, 81, 243, 16, 64, 256, 1024, 25, 125, 625, 3125]

b = sorted(a)
print b
>>[4, 8, 9, 16, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125]

c = dict().fromkeys(sorted(a)).keys()
print c
>> [32, 64, 4, 1024, 625, 8, 9, 256, 16, 81, 243, 3125, 25, 27, 125]

Другой метод с использованием наборов:

d = list(set(b))
print d
>> [32, 64, 4, 1024, 625, 8, 9, 256, 16, 81, 243, 3125, 25, 27, 125]   

What I expect is :
>>[4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125]

Кто-нибудь знает причину такого поведения?

Спасибо!

Ответы [ 5 ]

8 голосов
/ 07 февраля 2012

Вот что я бы использовал:

>>> a = [4, 8, 16, 32, 9, 27, 81, 243, 16, 64, 256, 1024, 25, 125, 625, 3125]
>>> sorted(set(a))
[4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125]

Причина, по которой ваш код не работает должным образом, заключается в том, что dict не гарантирует какой-либо конкретный порядок его ключей.Точно так же, set не имеет никаких гарантий относительно упорядочения своих элементов.

Следовательно, этап сортировки должен идти прямо в конце.

3 голосов
/ 07 февраля 2012

set() - неупорядоченная коллекция. Как словарь, он специально переставляет ключи для быстрого доступа. Следовательно: list(set(...)) возвращает список несортированных элементов. Используйте вместо:

sorted(set(...))

если вам нужна упорядоченная последовательность.

2 голосов
/ 07 февраля 2012

Python set был представлен в версии 2.3. Решение, предложенное @aix, наиболее Pythonic, если вы используете Python> = 2.3

В вашем коде следующая строка ...

c = dict().fromkeys(sorted(a)).keys()

создает dict с ключами от a и значениями по умолчанию None. А потом просто извлекает ключи, используя метод keys(). Поскольку словари не имеют определенного порядка, элементы выбираются случайным образом. Вы должны прибегнуть к ним. В любом случае вам действительно следует использовать sorted(set(a)), как уже предлагалось.

0 голосов
/ 07 февраля 2012
Словарь

не гарантирует итерацию (и печать) ключей в порядке вставки.

Используйте collections.OrderedDict для этого.

0 голосов
/ 07 февраля 2012

Метод keys возвращает ключи словаря в неопределенном (но согласованном между вызовами) порядке независимо от того, как создается словарь. [РЕДАКТИРОВАТЬ: как указано в комментарии, порядок остается неизменным, пока словарь остается неизменным.]

...