2012-02-05 2 views
2

파이썬 초보자는 값이 특정 숫자가 될 수있는 방식으로 두 개의 목록을 사전에 결합하는 방법이 있는지 알고 싶었습니다. 저는 여기에 결합하기 위해 노력하고있어 3 개 데이터 세트의 예리스트를 참조 속성으로리스트를 추가하는 방법이 있습니까?

[17, 39, 9] [13, 37, 13] = 0.13517353359 
[17, 39, 9] [15, 38, 10] = 0.055003044449 
[13, 39, 13] [13, 37, 13] = 0.0345037548204 
[13, 39, 13] [15, 38, 10] = 0.0801704891415 
[14, 39, 12] [13, 37, 13] = 0.0596711995129 
[14, 39, 12] [15, 38, 10] = 0.055003044449 
[15, 39, 11] [13, 37, 13] = 0.0848386442054 
[15, 39, 11] [15, 38, 10] = 0.0298355997564 
[16, 39, 10] [13, 37, 13] = 0.110006088898 
[16, 39, 10] [15, 38, 10] = 0.0298355997564 
정말 (내가 이미이 작업을 수행하는 기능을 가지고) 숫자를 정렬 할 수 및 첫 번째 목록에서 조회 할 할

(그러나 두 번째 목록을 참조로 필요로 함).

name = "%s-%s" % ([16, 39, 10], [15, 38, 10])과 같은 식으로 생각하고 (값이되는 숫자로) dict에 이름을 추가했지만이 문제는 [16, 39, 10]을 검색 할 수 없어 결과를 얻지 못했습니다. {[16, 39, 10] : [[15, 38, 10], 0.0298355997564]}와 같은 사전을 만들 수는 있지만 검색 기능이 중단됩니다.

내가 뭔가 이상한 행동을해야 할 수도 있다고 생각하지만, 더 좋은 방법이 있는지 알고 싶습니다. 이상적으로 나는 {[16, 39, 10]:0.0298355997564}과 [15, 38, 10]과 같은 간단한 dict를 원한다. 필요할 때 참조 할 수있는 일종의 속성이다.

이것이 가능합니까?

편집 : 자세한 내용 : 나중에 참조 할 필요가있는 경우를 대비하여 (이 특정 예에서는 [16, 39, 10] 두 번째 목록은 결과간에 차이가 있지만 전체 데이터 세트에는 많은 중복이 없으므로 특정 사례를 참조해야합니다.

+0

"하지만 참고로 두 번째 목록이 필요합니다"- 정확히 무엇을 의미합니까? – Wes

+0

나중에 참조 할 필요가있는 경우를 대비하여 필자가 필요로합니다 (이 특정 예에서는 [16, 39, 10]에 대한 중복을 발견했을 때 두 번째 목록을 사용하여 결과간에 차이를 만들지 만 전체 데이터 세트에서 필요합니다. 많은 경우 중복되지 않으므로 특정 사례를 참조하십시오.) – Lostsoul

+0

두 번째 목록을리스트 목록에 넣고 필요할 때만 참조하려고했으나 dicts에 번호가 매겨지지 않았기 때문에 논리를 알아낼 수 없었습니다 (따라서 dict의 위치 1은 위치 1과 관련이 없을 수 있습니다. list of list) – Lostsoul

답변

2

목록은 변경 가능하기 때문에 사전 키가 될 수 없습니다. 데이터가 정적 인 경우이를 튜플로 변환하여이를 키로 사용할 수 있습니다.값은 두 번째 목록 및 부동 소수점 값의 튜플 일 수도 있습니다.

data = { 
     (17, 39, 9): ([13, 37, 13], 0.13517353359), 
     (17, 39, 9): ([15, 38, 10], 0.055003044449), 
     (13, 39, 13): ([13, 37, 13], 0.0345037548204), 
    } 

    print "Other list:", d[(17, 39, 9)][0] 
    print "Float", d[(17, 39, 9)][1] 
+0

고맙습니다. 귀하의 코드를 시험해 보면 다른 목록 [15, 38, 10]에 대한 결과를 얻을 수 있지만 어떻게 첫 번째 항목에 액세스 할 수 있습니까? (17, 39, 9) : ([13, ​​37, 13], 0.13517353359). 첫 번째 항목이 두 번째 항목으로 덮어 쓰여지고있는 것처럼 보입니다. – Lostsoul

+0

방금 ​​데이터에 x를 입력했습니다. print x와 2 개의 항목 만 나열합니다. – Lostsoul

+0

@LostSoul : 서로 중복하는 DUPLICATES가 있기 때문에. –

2

해시 할 수 있도록 목록을 튜플로 변환해야합니다.

>>> l = [1,2,3] 
>>> d = { l: 5 } 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unhashable type: 'list' 
>>> t = tuple(l) 
>>> d = { t: 5 } 
>>> d[t] 
5 

그러나 질문을 다시 읽는 것은 전투의 절반 정도입니다. 또한 두 번째 목록도 검색 할 수 있기를 원합니다. 당신은 결과 나 두 번째 목록을 ... 필요로 할 때

d = { t: (second_list, result) } 

그런 다음,

other_list, result = d[t] 
당신은 튜플을 설명하기 위해 검색 기능을 수정해야 할 수 있습니다

는 하나가 아닌 사전에서 검색되는 값.

그런데 데이터 세트를 변경하지 않아도된다면 (두 개의 목록) 어쨌든 튜플을 만들 것을 고려해보십시오.

+0

그것은 시원했다! 나는 이런 방식으로 사용하지 않을 생각이었고, 또한 frozensets에 대해서도 몰랐다. 감사! 귀하의 코드에 약간의 문제가 있지만 데이터와 두 번째 목록에는 액세스 할 수 있지만 첫 번째 목록에는 액세스 할 수 없습니다 (예제에서는 t 값). 첫 번째 목록에 어떻게 액세스 할 수 있습니까? – Lostsoul

+0

@LostSoul : 네가 떨어져있는 동안 조쉬가 대답을 바꿨다. frozensets는 UNcool입니다. 내 대답을 보라. –

+0

@LostSoul : "어떻게 첫 번째 목록에 액세스 할 수 있습니까?"... 첫 번째 목록 (튜플이어야 함)은 사용자의 사전에 대한 KEY입니다. 사용자가 이미 알고 있어야하므로 데이터 번호와 두 번째 목록 (튜플이어야 함). –

0

공간이 약간 낭비되지만 두 개의 서로 다른 dict을 사용할 수 있습니다. 각 숫자는 첫 번째 숫자 집합으로 참조됩니다.

{(17,39,10): 0.13517353359, ...} 

당신이 해쉬로 키 필요하기 때문에 키가 아닌 목록으로 tuple의를 사용해야합니다
{(17,39,10): [13, 37, 13], ... } 

참고.

아하하지만 다른 번호와 목록이있는 중복 키가있는 것으로 나타났습니다. 그래서 당신은 평범한 오래된 dict을 사용할 수 없습니다 .... 당신은 이미 검색 기능이 있다고합니다. 어떤 데이터 구조가 작동합니까?

2

내가 같은 딕셔너리 만들 수 {[16, 39, 10] : [[15, 38, 10, 0.0298355997564]} 아니 당신은 할 수 없었다

. dict 키는 해시 가능해야합니다. 목록은 해시 가능하지 않습니다. 대신 목록으로 튜플을 사용할 수 있습니다

>>> x = {[16, 39, 10]:[[15, 38, 10], 0.0298355997564]} 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unhashable type: 'list' 
>>> x = {(16, 39, 10):[[15, 38, 10], 0.0298355997564]} 
>>> x 
{(16, 39, 10): [[15, 38, 10], 0.0298355997564]} 

는 튜플과 frozenset 사이의 선택 : frozensets 덜 효율적이다.

>>> (16, 39, 10) != (10, 39, 16) 
True # different 
>>> frozenset((16, 39, 10)) != frozenset((10, 39, 16)) 
False # same!! 

하지만 내 검색 기능을 나누기 : 더 중요 frozensets 순서가 유지되지 않습니다.

음, 네, 검색 기능을 변경해야합니다.

업데이트 여러 가지 중복을 허용합니다.

전체 테이블 스캔으로 항상 액세스 할 수있는 테이블 (목록)에 데이터가 저장되는 데이터베이스처럼 만들지 만 두 개의 인덱스 (defaultdict)를 각 외래 키에 하나씩 제공합니다.

코드 :

data = [ 
    ((17, 39, 9), (13, 37, 13), 0.13517353359), 
    ((17, 39, 9), (15, 38, 10), 0.055003044449), 
    ((13, 39, 13), (13, 37, 13), 0.0345037548204), 
    ((13, 39, 13), (15, 38, 10), 0.0801704891415), 
    ((14, 39, 12), (13, 37, 13), 0.0596711995129), 
    ((14, 39, 12), (15, 38, 10), 0.055003044449), 
    ((15, 39, 11), (13, 37, 13), 0.0848386442054), 
    ((15, 39, 11), (15, 38, 10), 0.0298355997564), 
    ((16, 39, 10), (13, 37, 13), 0.110006088898), 
    ((16, 39, 10), (15, 38, 10), 0.0298355997564), 
] 

from collections import defaultdict 
keydict1 = defaultdict(list) 
keydict2 = defaultdict(list) 
for row_index, row in enumerate(data): 
    tup1, tup2, value = row 
    keydict1[tup1].append(row_index) 
    keydict2[tup2].append(row_index) 

def search(keydict, query_tuple): 
    print 
    print "looking for", query_tuple 
    for row_index in keydict[query_tuple]: 
     print row_index, data[row_index] 

search(keydict1, (17, 39, 9)) 
search(keydict2, (13, 37, 13)) 

출력 :

looking for (17, 39, 9) 
0 ((17, 39, 9), (13, 37, 13), 0.13517353359) 
1 ((17, 39, 9), (15, 38, 10), 0.055003044449) 

looking for (13, 37, 13) 
0 ((17, 39, 9), (13, 37, 13), 0.13517353359) 
2 ((13, 39, 13), (13, 37, 13), 0.0345037548204) 
4 ((14, 39, 12), (13, 37, 13), 0.0596711995129) 
6 ((15, 39, 11), (13, 37, 13), 0.0848386442054) 
8 ((16, 39, 10), (13, 37, 13), 0.110006088898) 
관련 문제