2014-04-24 1 views
61

오늘 나는 예외를 던지지 않은 진술을 보았습니다. 누구든지 그 이론을 설명 할 수 있습니까?사전을 터플로 압축 해제 할 수없는 이유는 무엇입니까?

>>> x, y = {'a': 2, 'b': 5} 
>>> x 
'a' 
>>> y 
'b' 
+1

아래에서 언급하지 않았으므로이 디자인 결정은 유용성에 영향을 받았을 가능성이 높습니다. dict은 키를 제공 할 때 암시 적으로 해당 값에 대한 액세스 권한을 부여합니다. 대신 값을 반환하면 키에 액세스하는 것이 더 어려워집니다. –

답변

63

는 파이썬에서, 모든 iterable1 압축 해제 할 수 있습니다

>>> x,y,z = [1, 2, 3] # A list 
>>> x,y,z 
(1, 2, 3) 
>>> x,y,z = 1, 2, 3 # A tuple 
>>> x,y,z 
(1, 2, 3) 
>>> x,y,z = {1:'a', 2:'b', 3:'c'} # A dictionary 
>>> x,y,z 
(1, 2, 3) 
>>> x,y,z = (a for a in (1, 2, 3)) # A generator 
>>> x,y,z 
(1, 2, 3) 
>>> 

또한, 사전 반복하는 것은 단지 그 키를 반환하기 때문에 (사전을 풀고

>>> for i in {1:'a', 2:'b', 3:'c'}: 
...  print i 
... 
1 
2 
3 
>>> 

을하는 그 위로 반복)는 마찬가지로 키의 압축을 풉니 다.

>>> a,b,c = [1, 2, 3] # Number of names == len(iterable) 
>>> 
>>> a,b = [1, 2, 3] # Too few names 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: too many values to unpack (expected 2) 
>>> 
>>> a,b,c,d = [1, 2, 3] # Too many names 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: need more than 3 values to unpack 
>>> 

그러나 이것은 단지입니다 :


1 사실, 나는 반복자의 길이를 동일로 모든 반복자는 풀고 로 이름을 압축 해제 할 수 있다고한다 Python 2.x의 경우. 키를 통해 dict 반복

>>> # Python 3.x interpreter 
... 
>>> a, *b, c = [1, 2, 3, 4] 
>>> a, b, c 
(1, [2, 3], 4) 
>>> 
>>> a, *b = [1, 2, 3, 4] 
>>> a, b 
(1, [2, 3, 4]) 
>>> 
>>> *a, b, c = [1, 2, 3, 4] 
>>> a, b, c 
([1, 2], 3, 4) 
>>> 
+0

아마도 모든 iterable을 압축 해제 할 수 있다는 의미일까요? – aIKid

+1

그렇습니다. 그러나 변경이 가능한 iterables (길이와 내용 모두)와 순서가없는 iterables의 경우에는 더 일반적이지 않습니다. 어디에서 열쇠를 감을 지 아무런 상상도 할 수 없으며, 당신에게 용기를 줄 방법이 없습니다. – aruisdante

+2

@aIKid, 무의미한 것이 아닙니다. –

20

순회 : 파이썬 3.x를, 당신은 당신이 필요 단지 이름에 어떤 (유한) 크기의 반복 가능한 압축을 해제 할 수있는 extended iterable unpacking 있습니다. dict 리터럴에는 정확히 두 개의 키가 있으므로이 키를 2 개의 튜플에 압축을 풀 수 있습니다.

dicts가 순서가 지정되어 있지 않고 x == 'b'y == 'a'이 해당 코드의 법적 결과 일 수 있기 때문에 일반적으로 좋은 방법은 아닙니다.

+0

그들은 순서가 없다는 언급에 감사드립니다. – Tarik

+0

Python 3.6에서 dicts가 주문되었습니다. – gerrit

+0

@gerrit : yes, cpython에서 구현 세부 사항. – geoffspear

7

뒤에 로켓 과학이 없습니다. dict은 iterable이며 각 반복에서 키를 반환합니다. tuple() 때문에, (만큼 그들은 유한만큼) 인수와 같은 반복자를받을 수 있습니다 :이보고

>>>tuple({'a': 2, 'b': 5}) 
('a','b') 

는, 도시 된 바와 같이 압축 풀기가 작동 추론하기 쉽습니다. 또한, 모든 유한 반복자는 압축을 풀 수 있습니다

data = {'a': 2, 'b': 5} 
for key in data: 
    print key 

포장 풀기 오브젝트 반복보다는 다른 아무것도 없다 당신이 사전을 반복 할 때

>>> i = iter(range(3)) 
>>> a,b,c = i 
>>> a,b,c 
(0, 1, 2) 
+0

비슷하게 우리는''> list ({ 'a': 2, 'b': 5})':)를 사용할 수 있습니다. –

+0

로켓 과학 없음 : D! +1 –

8

, 당신은 키 얻고있는 요소를 넣어 주어진 변수 :

keys = tuple(data) # gives ('a', 'b') 
x, y = ('a', 'b') 
5

반복 가능한 상황에서 dicts는 키의 (정렬되지 않은) 컬렉션으로 처리됩니다. DICT에 keys()를 호출 한 것과 같은 상태가된다 당신이 list(some_dict)을 암탉, 그러나

>>> d = {'a': 3, 'b': 5} 
>>> list(d) 
['a', 'b'] 
>>> d.keys() 
['a', 'b'] 

, 당신은 또한 더 많은 작업을 수행 할 수 있습니다.

당신은 압축을 풀 수 있습니다 모두 dict의 두 키 당신이 첫번째 쌍의 목록으로 바꿀 경우 값 :

>>> d = {'a': 3, 'b': 5} 
>>> d_pairs = d.items() 
>>> print d_pairs 
[('a', 3), ('b', 5)] 
>>> ((k1, v1), (k2, v2)) = d_pairs 
>>> print k1, v1, k2, v2 
a 3 b 5 

아니면 그냥 쌍을 원하는 경우

>>> p1, p2 = d_pairs 
>>> print p1, p2 
('a', 3) ('b', 5) 

또는 말하십시오, 다만 열쇠 :

>>> ((k1, _), (k2, _)) = d_pairs 
>>> print k1, k2 
a b 

등등.

하지만 사전에 - 파이썬에서뿐 아니라 일반적으로 의미가없는 방식으로 항목을 포함하기 때문에 items() (파이썬에서)도 겉으로보기에 임의의 순서로 항목을 반환합니다. 어떤 키를 알 수있는 방법은 어떤 변수에 저장되지 않습니다 : 보시다시피

>>> ((k1, v1), (k2, v2)) = {'bar': 3, 'foo': 5}.items() 
>>> print k1, v1, k2, v2 
foo 5 bar 3 

items()에 의해 반환 쌍의 순서는 자신의 정의 순서에 비해 반전했다.

+1

+1 언급 할 때, 포장 풀기. –