목록을 집합으로 변환하면 요소 순서가 변경됩니다.
최근에 나는 내가 변환하고 때 눈치 list
로 set
요소의 순서를 변경하고 문자로 정렬됩니다.
이 예를 고려하십시오.
x=[1,2,20,6,210]
print x
# [1, 2, 20, 6, 210] # the order is same as initial order
set(x)
# set([1, 2, 20, 210, 6]) # in the set(x) output order is sorted
내 질문은-
- 왜 이런 일이 발생합니까?
- 초기 주문을 잃지 않고 어떻게 설정 작업 (특히 차액 설정)을 할 수 있습니까?
A
set
는 정렬되지 않은 데이터 구조입니다.사용하지 말고
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
.
Python 3.6에서는 Python 2 및 3에 대한 또 다른 솔루션이 있습니다.set()
이제 순서를 유지 해야 하지만
>>> x = [1, 2, 20, 6, 210]
>>> sorted(set(x), key=x.index)
[1, 2, 20, 6, 210]
첫 번째 질문에 대한 답으로 집합은 집합 작업에 최적화 된 데이터 구조입니다. 수학적 집합과 마찬가지로 요소의 특정 순서를 적용하거나 유지하지 않습니다. 집합의 추상 개념은 순서를 적용하지 않으므로 구현이 필요하지 않습니다. 목록에서 집합을 만들 때 Python은 집합 작업을 효율적으로 수행 할 수있는 집합에 대해 사용하는 내부 구현의 요구에 따라 요소의 순서를 자유롭게 변경할 수 있습니다.
다른 답변에서 알 수 있듯이 세트는 요소 순서를 유지하지 않는 데이터 구조 (및 수학적 개념)입니다.
그러나 집합과 사전의 조합을 사용하면 원하는대로 얻을 수 있습니다. 다음 스 니펫을 사용해보세요.
# 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
Building on Sven's answer, I found using collections.OrderedDict like so helped me accomplish what you want plus allow me to add more items to the 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)])
If you want to add items but still treat it like a set you can just do:
z['nextitem']=None
And you can perform an operation like z.keys() on the dict and get the set:
z.keys()
[1, 2, 20, 6, 210]
An implementation of the highest score concept above that brings it back to a list:
def SetOfListInOrder(incominglist):
from collections import OrderedDict
outtemp = OrderedDict()
for item in incominglist:
outtemp[item] = None
return(list(outtemp))
Tested (briefly) on Python 3.6 and Python 2.7.
In case you have a small number of elements in your two initial lists on which you want to do set difference operation, instead of using collections.OrderedDict
which complicates the implementation and makes it less readable, you can use:
# initial lists on which you want to do set difference
>>> nums = [1,2,2,3,3,4,4,5]
>>> evens = [2,4,4,6]
>>> evens_set = set(evens)
>>> result = []
>>> for n in nums:
... if not n in evens_set and not n in result:
... result.append(n)
...
>>> result
[1, 3, 5]
Its time complexity is not that good but it is neat and easy to read.
It's because the set is an unordered data structure.
To maintain the order, you can do it this way:
x=[1,2,3,20,6,210,50,20];
print(sorted(set(x),key=x.index));
As you will see by that way you can do set operations without losing the original order.
Here's an easy way to do it:
x=[1,2,20,6,210]
print sorted(set(x))
참고URL : https://stackoverflow.com/questions/9792664/converting-a-list-to-a-set-changes-element-order
'code' 카테고리의 다른 글
논리 연산자의 서면 버전 (0) | 2020.09.19 |
---|---|
Java의 "코드가 너무 큼"컴파일 오류 (0) | 2020.09.19 |
ViewPager가 콘텐츠를 다시 그리지 않고 그대로 유지 / 비어 있음 (0) | 2020.09.19 |
Maven이 로컬 아티팩트를 찾지 못함 (0) | 2020.09.19 |
인스턴스를 시작할 때 ECU 유닛, CPU 코어 및 메모리는 무엇을 의미합니까? (0) | 2020.09.19 |