programing

목록을 집합으로 변환하면 요소 순서가 변경됩니다.

cafebook 2023. 7. 7. 21:06
반응형

목록을 집합으로 변환하면 요소 순서가 변경됩니다.

최근에 나는 내가 변환할 때listset요소의 순서가 변경되고 문자별로 정렬됩니다.

이 예를 고려해 보십시오.

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

제 질문은 -입니다.

  1. 왜 이런 일이 생기는 건가요?
  2. 어떻게 하면 초기 순서를 잃지 않고 작업(특히 차이 설정)을 설정할 수 있습니까?
  1. A은(는) 순서가 지정되지 않은 데이터 구조이므로 삽입 순서를 보존하지 않습니다.

  2. 이는 사용자의 요구 사항에 따라 다릅니다.일반 목록이 있고 목록의 순서를 유지하면서 일부 요소 집합을 제거하려면 목록 이해도를 사용하여 이 작업을 수행할 수 있습니다.

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

    빠른 멤버쉽 테스트와 삽입 순서 보존모두 지원하는 데이터 구조가 필요한 경우 Python 사전의 키를 사용할 수 있습니다. Python 3.7부터는 삽입 순서를 보존할 수 있습니다.

    >>> a = dict.fromkeys([1, 2, 20, 6, 210])
    >>> b = dict.fromkeys([6, 20, 1])
    >>> dict.fromkeys(x for x in a if x not in b)
    {2: None, 210: None}
    

    b여기서 실제로 주문할 필요는 없습니다. 사용할 수 있습니다.set뿐만 아니라.참고:a.keys() - b.keys()를 "" " " " " " " 로 합니다.set삽입 순서를 보존하지 않습니다.

    이전 버전의 Python에서는 다음을 대신 사용할 수 있습니다.

    >>> 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)])
    

Python 3.6에서는 이제 순서를 유지해야 하지만 Python 2와 3을 위한 다른 솔루션이 있습니다.

>>> x = [1, 2, 20, 6, 210]
>>> sorted(set(x), key=x.index)
[1, 2, 20, 6, 210]

아래 기능으로 중복 제거 및 순서 유지

def unique(sequence):
    seen = set()
    return [x for x in sequence if not (x in seen or seen.add(x))]

Python에서 순서를 유지하면서 목록에서 중복 항목을 제거하는 방법

첫 번째 질문에 답하면 집합은 집합 작업에 최적화된 데이터 구조입니다.수학적 집합과 마찬가지로 요소의 특정 순서를 적용하거나 유지하지 않습니다.집합의 추상 개념은 순서를 강제하지 않으므로 구현이 필요하지 않습니다.목록에서 집합을 만들면 Python은 집합에 사용하는 내부 구현의 필요에 따라 요소의 순서를 변경할 수 있으므로 집합 작업을 효율적으로 수행할 수 있습니다.

수학에는 집합과 순서 집합(오셋)이 있습니다.

  • set: 고유 요소의 순서가 지정되지 않은 컨테이너(구현)
  • oset: 고유 요소의 순서가 지정된 컨테이너(비구현)

Python에서는 세트만 직접 구현됩니다.일반 딕트 키(3.7+)로 oset를 에뮬레이트할 수 있습니다.

정해진

a = [1, 2, 20, 6, 210, 2, 1]
b = {2, 6}

코드

oset = dict.fromkeys(a).keys()
# dict_keys([1, 2, 20, 6, 210])

데모

반복실험이 제거되고 삽입 순서가 보존됩니다.

list(oset)
# [1, 2, 20, 6, 210]

딕트 키에 대한 설정과 같은 작업입니다.

oset - b
# {1, 20, 210}

oset | b
# {1, 2, 5, 6, 20, 210}

oset & b
# {2, 6}

oset ^ b
# {1, 5, 20, 210}

세부 사항

참고: 정렬되지 않은 구조는 정렬된 요소를 배제하지 않습니다.오히려 질서 유지가 보장되지 않습니다.예:

assert {1, 2, 3} == {2, 3, 1}                    # sets (order is ignored)

assert [1, 2, 3] != [2, 3, 1]                    # lists (order is guaranteed)

목록멀티셋(mset)이 두 가지 더 매력적인 수학적 데이터 구조임을 알게 되어 기뻐할 수 있습니다.

  • list: 반복실험을 허용하는 요소의 순서가 지정된 컨테이너(구현)
  • mset: 반복실험을 허용하는 요소의 순서가 지정되지 않은 컨테이너(Not Implemented)*

요약

Container | Ordered | Unique | Implemented
----------|---------|--------|------------
set       |    n    |    y   |     y
oset      |    y    |    y   |     n
list      |    y    |    n   |     y
mset      |    n    |    n   |     n*  

*멀티셋은 다음을 사용하여 간접적으로 에뮬레이트할 수 있습니다.collections.Counter()다중성(다양성)에 대한 딕트식 매핑

Python 3.8.2라는 코드 한 줄로 중복된 값을 제거하고 삽입 목록 순서를 유지할 수 있습니다.

mylist = ['b', 'b', 'a', 'd', 'd', 'c']

결과 = list"value: ""(mylist}의 값)
인쇄(인쇄)
>> ['b', 'a', 'd', 'c']
결과 = 목록(키(mylist)에서 제외)
인쇄(인쇄)
>> ['b', 'a', 'd', 'c']

다른 답에서 보듯이, 집합은 요소 순서를 보존하지 않는 데이터 구조(및 수학적 개념)입니다.

그러나 세트와 사전의 조합을 사용하면 원하는 대로 수행할 수 있습니다. 다음 스니펫을 사용해 보십시오.

# 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

스벤의 대답을 바탕으로 수집품을 사용하는 것을 발견했습니다.OrderedDict like는 당신이 원하는 것을 달성하는 데 도움이 되었고 딕트에 더 많은 항목을 추가할 수 있게 했습니다.

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()와 같은 작업을 수행하여 세트를 가져올 수 있습니다.

list(z.keys())
[1, 2, 20, 6, 210]

하나 더 간단한 방법은 빈 목록을 만드는 것입니다. "unique_list"를 입력하여 원래 목록에서 고유한 요소를 추가합니다. 예를 들어 다음과 같습니다.

unique_list=[]

for i in original_list:
    if i not in unique_list:
        unique_list.append(i)
    else:
        pass

이렇게 하면 순서를 유지할 뿐만 아니라 모든 고유한 요소를 얻을 수 있습니다.

대답은 늦었지만 팬더를 사용할 수 있습니다, 경찰관.순서를 보존하는 동안 목록을 변환할 영상 시리즈:

import pandas as pd
x = pd.Series([1, 2, 20, 6, 210, 2, 1])
print(pd.unique(x))

출력: 배열([1, 2, 20, 6, 210])

문자열 목록에서 작동합니다.

x = pd.Series(['c', 'k', 'q', 'n', 'p','c', 'n'])
print(pd.unique(x))

출력 ['c' 'k' 'q' 'n' 'p']

위의 최고 점수 개념을 구현하여 목록으로 되돌립니다.

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에서 (간단히) 테스트되었습니다.

두 개의 초기 목록에 사용하지 않고 차분 연산을 설정하려는 요소가 적은 경우collections.OrderedDict구현이 복잡해지고 읽기가 어려워지므로 다음을 사용할 수 있습니다.

# 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]

시간 복잡성은 별로 좋지 않지만 깔끔하고 읽기 쉽습니다.

사람들이 이론 과학의 정의에 대해 농담을 하기 위해 항상 '현실 세계 문제'를 사용한다는 것은 흥미로운 일입니다.

세트에 순서가 있으면 먼저 다음 문제를 파악해야 합니다.목록에 중복 요소가 있는 경우, 목록을 집합으로 전환할 때 순서는 무엇입니까?우리가 두 세트를 합칠 경우 순서가 어떻게 됩니까?동일한 요소에서 순서가 다른 두 집합을 교차하면 순서가 어떻게 됩니까?

또한 세트 작업에 매우 적합한 특정 키를 검색하는 속도가 훨씬 빠릅니다(목록이 아닌 세트가 필요한 이유).

만약 당신이 정말로 인덱스에 관심이 있다면, 그것을 목록으로 유지하세요.여전히 많은 목록의 요소에 대해 설정 작업을 수행하려는 경우, 가장 간단한 방법은 원래 목록에 있는 키의 모든 인덱스를 포함하는 목록 값과 세트에 있는 동일한 키를 사용하여 각 목록에 대한 사전을 만드는 것입니다.

def indx_dic(l):
    dic = {}
    for i in range(len(l)):
        if l[i] in dic:
            dic.get(l[i]).append(i)
        else:
            dic[l[i]] = [i]
    return(dic)

a = [1,2,3,4,5,1,3,2]
set_a  = set(a)
dic_a = indx_dic(a)

print(dic_a)
# {1: [0, 5], 2: [1, 7], 3: [2, 6], 4: [3], 5: [4]}
print(set_a)
# {1, 2, 3, 4, 5}

컬렉션을 사용할 수 있습니다.에 대한 카운터:

# tested on python 3.7
>>> from collections import Counter
>>> lst = ["1", "2", "20", "6", "210"]

>>> for i in Counter(lst):
>>>     print(i, end=" ")
1 2 20 6 210 

>>> for i in set(lst):
>>>     print(i, end=" ")
20 6 2 1 210

원하는 경우 중복된 값을 제거하고 삽입 목록 순서를 유지할 수 있습니다.

lst = [1,2,1,3]
new_lst = []

for num in lst :
    if num not in new_lst :
        new_lst.append(num)

# new_lst = [1,2,3]

'주문'을 원하는 경우 중복 제거에 '세트'를 사용하지 마십시오.

검색을 위해 집합을 사용합니다.
x인 리스트
O(n) 시간이 걸립니다.
어디에
세트로 x
O(1) 시간 소요 *대부분의 경우

이를 위한 쉬운 방법은 다음과 같습니다.

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

반응형