당신이 가지고 있다고 상상해보십시오 :
keys = ['name', 'age', 'food']
values = ['Monty', 42, 'spam']
다음 사전을 만드는 가장 간단한 방법은 무엇입니까?
a_dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
답변
이처럼 :
>>> keys = ['a', 'b', 'c']
>>> values = [1, 2, 3]
>>> dictionary = dict(zip(keys, values))
>>> print(dictionary)
{'a': 1, 'b': 2, 'c': 3}
Voila 🙂 pairwise dict
생성자와 zip
함수는 매우 유용합니다 : https://docs.python.org/3/library/functions.html#func-dict
답변
당신이 가지고 있다고 상상해보십시오 :
keys = ('name', 'age', 'food') values = ('Monty', 42, 'spam')
다음 사전을 생성하는 가장 간단한 방법은 무엇입니까?
dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
성능이 가장 뛰어난 dict
생성자zip
new_dict = dict(zip(keys, values))
Python 3에서 zip은 이제 lazy iterator를 반환하며 이것이 가장 성능이 좋은 방법입니다.
dict(zip(keys, values))
dict
및 zip
에 대한 일회성 전역 조회가 각각 필요 하지만 불필요한 중간 데이터 구조를 형성하지 않거나 함수 애플리케이션에서 로컬 조회를 처리해야합니다.
준우승, 독해 :
dict 생성자를 사용하는 데 가장 근접한 것은 dict 이해의 기본 구문을 사용하는 것입니다 ( 다른 사람들이 실수로 말한 것처럼 목록 이해가 아님 ).
new_dict = {k: v for k, v in zip(keys, values)}
키 또는 값을 기준으로 매핑하거나 필터링해야 할 때이 옵션을 선택하십시오.
Python 2에서는 zip
불필요한 목록을 만들지 않으려면 목록을 반환하고 izip
대신 사용하십시오 (zip으로 별칭을 지정하면 Python 3으로 이동할 때 코드 변경을 줄일 수 있습니다).
from itertools import izip as zip
따라서 여전히 (2.7)입니다.
new_dict = {k: v for k, v in zip(keys, values)}
파이썬 2, <= 2.6에 이상적
izip
from itertools
는 zip
Python 3 izip
이 됩니다 . 불필요한 목록 생성을 피하기 때문에 Python 2의 zip보다 낫고 2.6 이하에 이상적입니다.
from itertools import izip
new_dict = dict(izip(keys, values))
모든 경우에 대한 결과 :
모든 경우에:
>>> new_dict
{'age': 42, 'name': 'Monty', 'food': 'spam'}
설명:
도움말을 dict
보면 다양한 형식의 인수가 필요하다는 것을 알 수 있습니다.
>>> help(dict)
class dict(object)
| dict() -> new empty dictionary
| dict(mapping) -> new dictionary initialized from a mapping object's
| (key, value) pairs
| dict(iterable) -> new dictionary initialized as if via:
| d = {}
| for k, v in iterable:
| d[k] = v
| dict(**kwargs) -> new dictionary initialized with the name=value pairs
| in the keyword argument list. For example: dict(one=1, two=2)
최적의 접근 방식은 불필요한 데이터 구조를 만들지 않으면 서 이터 러블을 사용하는 것입니다. Python 2에서 zip은 불필요한 목록을 만듭니다.
>>> zip(keys, values)
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
Python 3에서 이에 해당하는 것은 다음과 같습니다.
>>> list(zip(keys, values))
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
파이썬 3은 zip
단순히 반복 가능한 객체를 만듭니다.
>>> zip(keys, values)
<zip object at 0x7f0e2ad029c8>
불필요한 데이터 구조를 만드는 것을 피하고 싶기 때문에, 파이썬 2 zip
는 불필요한리스트를 생성하기 때문에 피하는 것이 좋습니다.
성능이 떨어지는 대안 :
이것은 dict 생성자에 전달되는 생성기 표현식입니다.
generator_expression = ((k, v) for k, v in zip(keys, values))
dict(generator_expression)
또는 동등하게 :
dict((k, v) for k, v in zip(keys, values))
그리고 이것은 dict 생성자에게 전달되는 목록 이해입니다.
dict([(k, v) for k, v in zip(keys, values)])
처음 두 경우에는 작동 불가능한 (따라서 불필요한) 계산의 추가 계층이 zip iterable 위에 배치되고 목록 이해의 경우 추가 목록이 불필요하게 작성됩니다. 나는 그들 모두 성능이 떨어질 것이라고 기대할 것입니다.
성능 검토 :
Ubuntu 16.04에서 Nix가 제공하는 64 비트 Python 3.8.2에서 가장 빠른 것부터 가장 느린 것까지 순서 :
>>> min(timeit.repeat(lambda: dict(zip(keys, values))))
0.6695233230129816
>>> min(timeit.repeat(lambda: {k: v for k, v in zip(keys, values)}))
0.6941362579818815
>>> min(timeit.repeat(lambda: {keys[i]: values[i] for i in range(len(keys))}))
0.8782548159942962
>>>
>>> min(timeit.repeat(lambda: dict([(k, v) for k, v in zip(keys, values)])))
1.077607496001292
>>> min(timeit.repeat(lambda: dict((k, v) for k, v in zip(keys, values))))
1.1840861019445583
dict(zip(keys, values))
작은 키와 값 세트로도 승리하지만 더 큰 세트의 경우 성능 차이가 커집니다.
한 논평자는 말했다 :
min
성능을 비교하는 나쁜 방법 인 것 같습니다. 확실히mean
및 / 또는max
실제 사용에 대한 훨씬 더 유용한 지표가 될 것입니다.
min
이러한 알고리즘은 결정론 적이므로 사용 합니다. 최상의 조건에서 알고리즘의 성능을 알고 싶습니다.
어떤 이유로 든 운영 체제가 중단되면 비교하려는 것과 아무런 관련이 없으므로 이러한 유형의 결과를 분석에서 제외해야합니다.
를 사용 mean
하면 이러한 종류의 이벤트가 결과를 크게 왜곡하고 사용 max
하면 가장 극단적 인 결과 만 얻을 수 있습니다.
논평자는 또한 말합니다 :
python 3.6.8에서 평균 값을 사용하면 작은 목록의 경우 dict 이해력이 여전히 약 30 % 빠릅니다. 더 큰 목록 (10k 난수)의 경우
dict
통화가 약 10 % 빠릅니다.
dict(zip(...
10k의 난수를 의미한다고 가정 합니다. 그것은 꽤 특이한 사용 사례처럼 들립니다. 가장 직접적인 호출은 큰 데이터 세트에서 지배적이며, OS 테스트가 해당 테스트를 실행하는 데 걸리는 시간이 오래 걸리고 숫자가 더 치우친 경우 놀라지 않을 것입니다. 그리고 당신이 사용하는 경우 mean
또는 max
나는 결과의 의미를 고려할 것입니다.
우리의 주요 예에서보다 현실적인 크기를 사용합시다.
import numpy
import timeit
l1 = list(numpy.random.random(100))
l2 = list(numpy.random.random(100))
그리고 우리 dict(zip(...
는 더 큰 데이터 세트에 대해 실제로 약 20 % 더 빠르게 실행 되는 것을 볼 수 있습니다 .
>>> min(timeit.repeat(lambda: {k: v for k, v in zip(l1, l2)}))
9.698965263989521
>>> min(timeit.repeat(lambda: dict(zip(l1, l2))))
7.9965161079890095
답변
이 시도:
>>> import itertools
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> adict = dict(itertools.izip(keys,values))
>>> adict
{'food': 'spam', 'age': 42, 'name': 'Monty'}
Python 2에서는에 비해 메모리 소비가 더 경제적입니다 zip
.
답변
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> dict(zip(keys, values))
{'food': 'spam', 'age': 42, 'name': 'Monty'}
답변
Python ≥ 2.7에서 사전 이해를 사용할 수도 있습니다.
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> {k: v for k, v in zip(keys, values)}
{'food': 'spam', 'age': 42, 'name': 'Monty'}
답변
보다 자연스러운 방법은 사전 이해력을 사용하는 것입니다
keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')
dict = {keys[i]: values[i] for i in range(len(keys))}
답변
사전을 작성하기 전에 키 또는 값을 변환해야하는 경우 생성기 표현식 을 사용할 수 있습니다. 예:
>>> adict = dict((str(k), v) for k, v in zip(['a', 1, 'b'], [2, 'c', 3]))