문자열 목록을 정수 목록에 매핑하는 방법 [중복]

Nov 14 2020

n 개의 요소가있는 목록이 있습니다.

['pea', 'rpai', 'rpai', 'schiai', 'pea', 'rpe', 'zoi', 'zoi', 'briai', 'rpe']

각 문자열에 숫자를 할당하고 처음에는 0을 할당 한 다음 요소가 다르면 1 씩 증가하고 대신 요소가 반복되면 동일한 숫자를 제공해야합니다. 예:

['pea', 'rpai', 'rpai', 'schiai', 'pea', 'rpe', 'zoi', 'zoi', 'briai', 'rpe']
[ 0,    1,      1,      2,        0,     3,     4,     4,     5,       3    ]

내가 어떻게 해?

답변

14 superbrain Nov 14 2020 at 21:08

도우미 사전 사용 :

>>> [*map({k: v for v, k in enumerate(dict.fromkeys(final))}.get, final)]
[0, 1, 1, 2, 0, 3, 4, 4, 5, 3]

또 다른 방법:

>>> d = {}
>>> [d.setdefault(x, len(d)) for x in final]
[0, 1, 1, 2, 0, 3, 4, 4, 5, 3]
10 algorythms Nov 14 2020 at 20:56

사전을 사용하면 이것을 얻을 수 있습니다.

def counts(a):
    dis = {}
    count=0
    for i in range(len(a)):
        if a[i] not in dis.keys():
            dis[a[i]] = count
            count+=1
        
    return([dis[x] for x in a])
6 JLPeyret Nov 14 2020 at 23:52

용도 defaultdict를 하고 기본 값 함수로 카운터를 사용합니다.

키가 존재할 때마다 저장된 "처음 발견 된 위치"를 반환합니다. 그렇지 않으면 Incr.__call__계수를 증가시켜 새로운 첫 번째 발견 위치를 제공합니다.

슈퍼 브레인의 제안에 따라 기존 카운터 클래스를 사용하십시오.

from collections import defaultdict 
from itertools import count

li = ['pea', 'rpai', 'rpai', 'schiai', 'pea', 'rpe', 'zoi', 'zoi', 'briai', 'rpe']
seen = defaultdict(count().__next__)
print( [seen[val] for val in li] )

이전과 같이 내 증분을 롤링하면 GUID와 같은 모든 항목을 반환 할 수 있다는 이점이 있습니다.

from collections import defaultdict 

class Incr:
    def __init__(self):
        self.count = -1

    def __call__(self):
        self.count +=1 
        return self.count

li = ['pea', 'rpai', 'rpai', 'schiai', 'pea', 'rpe', 'zoi', 'zoi', 'briai', 'rpe']

seen = defaultdict(Incr())

print( [seen[val] for val in li] )

둘 다 동일한 출력을 제공합니다.

[0, 1, 1, 2, 0, 3, 4, 4, 5, 3]
3 dimay Nov 14 2020 at 20:54

이 시도:

a = ['pea', 'rpai', 'rpai', 'schiai', 'pea', 'rpe', 'zoi', 'zoi', 'briai', 'rpe']
dct = {}
counter = 0
for i in range(len(a)):
    if a[i] not in dct.keys():
        dct[a[i]] = counter 
        counter += 1
print([(i, dct[i]) for i in a])
2 Somethink Nov 14 2020 at 20:54

이미 가지고 있다면 증명 만하면됩니다.

def counts(final):
    count3 = [] # contains all objects that were already found
    count2=[]
    count=0
    for x in final:
        if x not in count3: # test if it's not already in count3
            count+=1
            count2.append(count)
            count3.append(x)
        else:
            count2.append(count)
    
return count2
1 Hamza Nov 15 2020 at 00:38

가장 깨끗한 방법은 팬더를 사용하는 것입니다.

import pandas as pd
lst =  ['pea', 'rpai', 'rpai', 'schiai', 'pea', 'rpe', 'zoi', 'zoi', 'briai', 'rpe']
pd.factorize(lst)

출력되는 내용 :

(array([0, 1, 1, 2, 0, 3, 4, 4, 5, 3], dtype=int64),
 array(['pea', 'rpai', 'schiai', 'rpe', 'zoi', 'briai'], dtype=object))
JoeFerndz Nov 14 2020 at 21:16

나는 틀린 것으로 판명되었고 사전을 사용해야합니다 (@Steve에게 감사드립니다). 다음은 사전이 포함 된 업데이트 된 버전입니다.

a = ['pea', 'rpai', 'rpai', 'schiai', 'pea', 'rpe', 'zoi', 'zoi', 'briai', 'rpe']
b = [None]*len(a)
d = {}
for i,x in enumerate(a):
    if x not in d: d[x] = len (d) #or use d.setdefault(x, len(d)) instead of the if statement (using the algo from @superb rain's)
    b[i] = d[x]    

print (a)
print (b)

이 결과는 다음과 같습니다.

['pea', 'rpai', 'rpai', 'schiai', 'pea', 'rpe', 'zoi', 'zoi', 'briai', 'rpe']
[0, 1, 1, 2, 0, 3, 4, 4, 5, 3]