dicts
(точно так же, как set
s, когда вам не нужно связывать значение с каждым ключом, а просто записывать, присутствует или отсутствует ключ), в значительной степени оптимизированы. Создание dict
из N ключей или пар ключ / значение - O(N)
, выборка - O(1)
, амортизация - O(1)
и т. Д. На самом деле не может сделать ничего существенно лучше для любого не крошечного контейнера!
Для крошечных контейнеров вы можете легко проверить границы с помощью timeit
эталонных тестов. Например:
$ python -mtimeit -s'empty=()' '23 in empty'
10000000 loops, best of 3: 0.0709 usec per loop
$ python -mtimeit -s'empty=set()' '23 in empty'
10000000 loops, best of 3: 0.101 usec per loop
$ python -mtimeit -s'empty=[]' '23 in empty'
10000000 loops, best of 3: 0.0716 usec per loop
$ python -mtimeit -s'empty=dict()' '23 in empty'
10000000 loops, best of 3: 0.0926 usec per loop
это показывает, что проверка членства в пустых списках или кортежах быстрее, на целых 20-30 наносекунд, чем проверка членства в пустых наборах или диктовках; когда важна каждая наносекунда, эта информация может иметь отношение к вам. Поднимаясь немного ...:
$ python -mtimeit -s'empty=range(7)' '23 in empty'
1000000 loops, best of 3: 0.318 usec per loop
$ python -mtimeit -s'empty=tuple(range(7))' '23 in empty'
1000000 loops, best of 3: 0.311 usec per loop
$ python -mtimeit -s'empty=set(range(7))' '23 in empty'
10000000 loops, best of 3: 0.109 usec per loop
$ python -mtimeit -s'empty=dict.fromkeys(range(7))' '23 in empty'
10000000 loops, best of 3: 0.0933 usec per loop
Вы видите, что для контейнеров из 7 предметов (не считая интересующего) баланс производительности сместился, и теперь у диктовок и наборов есть преимущества на СТО наносекунд. Когда предмет интереса присутствует:
$ python -mtimeit -s'empty=range(7)' '5 in empty'
1000000 loops, best of 3: 0.246 usec per loop
$ python -mtimeit -s'empty=tuple(range(7))' '5 in empty'
1000000 loops, best of 3: 0.25 usec per loop
$ python -mtimeit -s'empty=dict.fromkeys(range(7))' '5 in empty'
10000000 loops, best of 3: 0.0921 usec per loop
$ python -mtimeit -s'empty=set(range(7))' '5 in empty'
10000000 loops, best of 3: 0.112 usec per loop
дикты и наборы не дают большого выигрыша, но кортежи и списки выигрывают, даже несмотря на то, что диктаты и наборы остаются значительно быстрее.
И так далее, и так далее - timeit
упрощает запуск микро-эталонов (строго говоря, гарантированно только в тех чрезвычайно редких ситуациях, когда наносекунды имеют значение, но достаточно легко, что это не так). большие трудности для проверки ДРУГИХ случаев; -).