2012-02-07 12 views
3

У меня есть список целых чисел.странное поведение при удалении дубликатов в списке

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

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] 

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

Спасибо!

ответ

8

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

>>> 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 не имеет гарантий относительно порядка его элементов.

Следовательно, шаг сортировки должен быть в конце.

+1

Собственно, это на самом деле то, что я сделал. , , порядок обращений функций. Ваш способ сделать это кажется лучше. – jlengrand

+0

Также рассмотрите возможность использования frozenset, когда вы знаете, что он не будет изменчивым. В этом случае не имеет значения, но позволяет хешировать, таким образом, размещать в другом наборе или словаре, если вы делаете это для нескольких целых комбинаций. –

+0

Спасибо, я смотрю на это. Много нового словарного запаса для меня здесь :) – jlengrand

0

Метод keys возвращает ключи словаря в неопределенном (хотя и согласованном между вызовами) порядке, независимо от того, как создается словарь. [EDIT: как указано в комментарии, порядок согласован, если словарь остается неизменным.]

+1

Заказ может измениться при добавлении или удалении ключей. –

0

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

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

3

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

sorted(set(...)) 

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

+0

Это не отвечает на вопрос ОП. –

+0

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

2

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

В своем коде, в следующей строке ...

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

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

+0

Я не вижу смысла использовать 'sorted' в любом случае. Если что-нибудь, что вы бы использовали, отсортировано снаружи: c = sorted (dict(). Fromkeys (a) .keys()). Нет смысла делать это по-другому. –

+0

Согласен. Похоже, что OP пришел к возможному решению, выполнив быстрый поиск в Интернете ... «Я видел два разных решения в Интернете». И решение, которое он нашел, очень устарело. И он спросил: «Кто-нибудь знает причину такого поведения?» Поэтому я просто пытался объяснить поведение. Как уже упоминалось, 'sorted (set (a))' - правильный способ решить эту проблему. –

Смежные вопросы