Почему set.add () переупорядочивает элементы? [Дубликат]

Другой распространенной причиной задержек в потоке пользовательского интерфейса является доступ SharedPreferences. Когда вы впервые вызываете PreferenceManager.getSharedPreferences и другие подобные методы, соответствующий файл .xml сразу загружается и анализируется в том же потоке .

Один из хороших способов Борьба с этой проблемой вызывает сначала загрузку SharedPreference из фонового потока, как можно раньше (например, из onCreate вашего класса Application). Таким образом, объект предпочтения может быть уже сконструирован к тому моменту, когда вы захотите его использовать.

К сожалению, иногда чтение файлов предпочтений необходимо на ранних этапах запуска (например, в начальной операции или даже в приложении сам). В таких случаях по-прежнему можно избежать срыва UI с помощью MessageQueue.IdleHandler. Сделайте все, что вам нужно для выполнения в основном потоке, а затем установите IdleHandler для выполнения кода, как только ваша активность будет полностью нарисована. В этом Runnable вы должны иметь доступ к SharedPreferences, не задерживая слишком много операций рисования и делая Хореографа недовольными.

60
задан Kevin Guan 15 January 2016 в 05:59
поделиться

7 ответов

  1. A set является неупорядоченной структурой данных.
  2. Не используйте set , а скорее collections.OrderedDict :
    >>> a = collections.OrderedDict.fromkeys([1, 2, 20, 6, 210])
    >>> b = collections.OrderedDict.fromkeys([6, 20, 1])
    >>> collections.OrderedDict.fromkeys(x for x in a if x not in b)
    OrderedDict([(2, None), (210, None)])
    
    Обратите внимание, что порядок b не имеет значения, поэтому он может быть любым итерабельным, но должен быть итерабельным, который поддерживает тесты на членство O (1).

Изменить: В приведенном выше ответе предполагается, что вы хотите выполнять (упорядоченно) заданные операции во всех встречающихся коллекциях, в частности, также и в результате предыдущей заданной операции. Если это не обязательно, вы можете просто использовать списки для некоторых коллекций и устанавливать для других, например

>>> a = [1, 2, 20, 6, 210]
>>> b = set([6, 20, 1])
>>> [x for x in a if x not in b]
[2, 210]

. Это теряет порядок b, не позволяет быстро проверять членство в a и результат. Наборы позволяют быстро проверять членство, а списки сохраняют порядок. Если вам нужны обе эти функции в одной коллекции, используйте collections.OrderedDict.

59
ответ дан tsherwen 19 August 2018 в 10:29
поделиться
  • 1
    Ни один объект не стоит 16 байт. Если есть только заданный по умолчанию OrderedSet (). :( – Sean 6 November 2017 в 09:43

Вот простой способ сделать это:

x=[1,2,20,6,210]
print sorted(set(x))
-7
ответ дан dorukayhan 19 August 2018 в 10:29
поделиться

Основываясь на ответе Свена, я нашел использование коллекций. Такой способ помог мне выполнить то, что вы хотите, и позволить мне добавить больше элементов в dict:

import collections

x=[1,2,20,6,210]
z=collections.OrderedDict.fromkeys(x)
z
OrderedDict([(1, None), (2, None), (20, None), (6, None), (210, None)])

Если вы хотите добавить элементы, но все еще рассматривайте его как набор, который вы можете просто сделать:

z['nextitem']=None

И вы можете выполнить операцию типа z.keys () на dict и получить набор:

z.keys()
[1, 2, 20, 6, 210]
1
ответ дан jimh 19 August 2018 в 10:29
поделиться
  • 1
    вам нужно сделать list(z.keys()), чтобы получить вывод списка. – jxn 16 December 2017 в 00:09
  • 2
    в Python 3, да. не в Python 2, хотя я должен был указать. – jimh 16 December 2017 в 01:00

Как указано в других ответах, наборы представляют собой структуры данных (и математические концепции), которые не сохраняют порядок элементов -

Однако, используя комбинацию множеств и словарей, возможно, что вы можете добиваться того, что вы хотите - попробуйте использовать эти фрагменты:

# save the element order in a dict:
x_dict = dict(x,y for y, x in enumerate(my_list) )
x_set = set(my_list)
#perform desired set operations
...
#retrieve ordered list from the set:
new_list = [None] * len(new_set)
for element in new_set:
   new_list[x_dict[element]] = element
3
ответ дан jsbueno 19 August 2018 в 10:29
поделиться

Отвечая на ваш первый вопрос, установите структуру данных, оптимизированную для операций с множеством, и как математический набор, она не обеспечивает / не поддерживает какой-либо конкретный порядок элементов. Абстрактная концепция набора не обеспечивает порядок, поэтому реализация не выполняется. Когда вы создаете набор из списка, python позволяет изменять порядок элементов для нужд внутренней реализации, которые он использует для набора, который может эффективно выполнять заданные операции.

13
ответ дан lvella 19 August 2018 в 10:29
поделиться

Реализация высшей концепции оценки выше, что приносит его обратно к списку:.

def SetOfListInOrder(incominglist):
    from collections import OrderedDict
    outtemp = OrderedDict()
    for item in incominglist:
        outtemp[item] = None
    return(list(outtemp))

Испытано (кратко) на Python 3.6 и Python 2.7

0
ответ дан Mike Stucka 19 August 2018 в 10:29
поделиться

В Python 3.6, set() теперь должен сохранить порядок, но есть другое решение для Python 2 и 3:

>>> x = [1, 2, 20, 6, 210]
>>> sorted(set(x), key=x.index)
[1, 2, 20, 6, 210]
17
ответ дан Tiger-222 19 August 2018 в 10:29
поделиться
  • 1
    Две записи о сохранении заказа: только с Python 3.6, и даже там, это считается деталью реализации, поэтому не полагайтесь на нее. Кроме того, ваш код очень неэффективен, потому что каждый раз, когда вызывается x.index, выполняется линейный поиск. Если у вас все в порядке с квадратичной сложностью, нет оснований использовать set в первую очередь. – Thijs van Dien 29 December 2016 в 12:56
  • 2
    @ThijsvanDien Это неправильно, set() не упорядочен в Python 3.6, даже не как деталь реализации, вы думаете о dict s – Chris_Rands 9 August 2017 в 12:06
  • 3
    @Chris_Rands Я стою исправлено; они, похоже, сортируются, а не сохраняют порядок вставки. В любом случае: деталь реализации. – Thijs van Dien 9 August 2017 в 17:47
  • 4
    @ThijsvanDien Нет, они не отсортированы, хотя иногда появляются так, потому что int часто используют хэш для себя stackoverflow.com/questions/45581901/… – Chris_Rands 9 August 2017 в 18:26
  • 5
    Попробуйте x=[1,2,-1,20,6,210] и сделайте его набором. Вы увидите, что он вообще не заказан, проверен на Python 3.6. – GabrielChu 8 July 2018 в 01:50
Другие вопросы по тегам:

Похожие вопросы: