Заказывать вещи в питоне ...? - PullRequest
3 голосов
/ 20 августа 2011

У меня сложилось впечатление, что set () будет заказывать коллекцию так же, как .sort ()

Однако кажется, что это не так, для меня было характерным то, почему он переупорядочил коллекцию.

>>> h = '321'
>>> set(h)
set(['1', '3', '2'])
>>> h
'321'
>>> h = '22311'
>>> set(h)
set(['1', '3', '2'])

почему он не возвращает set (['1', '2', '3']). Мне также кажется, что независимо от того, сколько экземпляров каждого числа я использую или в каком порядке я их использую, он всегда возвращает set (['1', '3', '2']). Почему?

Edit:

Итак, я прочитал ваши ответы, и вот мой счетчик:

>>> l = [1,2,3,3]
>>> set(l)
set([1, 2, 3])
>>> l = [3,3,2,3,1,1,3,2,3]
>>> set(l)
set([1, 2, 3])

Почему он заказывает числа, а не строки?

Также

import random
l = []
for itr in xrange(101):
    l.append(random.randint(1,101))

print set(l)

Выходы

>>> 
set([1, 2, 4, 5, 6, 8, 10, 11, 12, 14, 15, 16, 18, 19, 23, 24, 25, 26, 29, 30, 31, 32, 34, 40, 43, 45, 46, 47, 48, 49, 50, 51, 53, 54, 55, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 69, 70, 74, 75, 77, 79, 80, 83, 84, 85, 87, 88, 89, 90, 93, 94, 96, 97, 99, 101])

Ответы [ 3 ]

4 голосов
/ 20 августа 2011

python set неупорядочен, поэтому нет никакой гарантии, что элементы будут упорядочены так же, как вы их указали

Если вы хотите отсортированный вывод, то вызовите sorted:

sorted(set(h))

Отвечая на ваше редактирование: все сводится к реализации множества.В CPython это сводится к двум вещам:

1) набор будет отсортирован по хешу (функция __hash__) по модулю предела

2) предел обычно следующий по величинестепень 2

Итак, давайте посмотрим на случай int:

x=1
type(x) # int
x.__hash__() # 1

для целых чисел, хеш равен исходному значению:

[x==x.__hash__() for x in xrange(1000)].count(False) # = 0

Следовательно, когда всезначения являются целочисленными, он будет использовать целочисленное значение хеша, и все будет работать гладко.

для строковых представлений, хэши не работают одинаково:

x='1'
type(x)  
# str
x.__hash__()
# 6272018864

Чтобы понять, почему сортировка прерываетсядля ['1', '2', '3'] посмотрите эти хеш-значения:

[str(x).__hash__() for x in xrange(1,4)]
# [6272018864, 6400019251, 6528019634]

В нашем примере значение мода равно 4 (3 elts, 2 ^ 1 = 2, 2^ 2 = 4) так

[str(x).__hash__()%4 for x in xrange(1,4)]
# [0, 3, 2]
[(str(x).__hash__()%4,str(x)) for x in xrange(1,4)]
# [(0, '1'), (3, '2'), (2, '3')]

Теперь, если вы отсортируете этого зверя, вы получите порядок, который вы видите в наборе:

[y[1] for y in sorted([(str(x).__hash__()%4,str(x)) for x in xrange(1,4)])]
# ['1', '3', '2']
1 голос
/ 20 августа 2011

Набор в Python пытается быть «набором» в математическом смысле этого термина.Нет дубликатов, и порядок не должен иметь значения.

1 голос
/ 20 августа 2011

Из документации python типа set :

Объект set представляет собой неупорядоченную коллекцию различных объектов hashable.

Это означает, что в наборе нет понятия порядка элементов в нем.Вы не должны удивляться, когда элементы печатаются на экране в необычном порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...