deque are implemented a little smarter than just doubly-linked lists. They're a doubly-linked list of blocks of Python objects, where the left and right sides may be incomplete blocks.
The Big-O cost of accessing in the middle is still O(n), but it has a constant divisor (implementation dependent, CPython 3.5 allocates blocks that can store 64 objects). So if your deque has 1000 members, accessing in the middle still involves only around 7-8 "linked list-style" traversals, not 500-some. If the deque is smallish (65 to 128 elements, depending on how the empty slots align with the head and tail blocks), then lookup of any element is equal cost.
The CPython deque is implemented as a doubly linked list (https://github.com/python/cpython/blob/v3.8.1/Modules/_collectionsmodule.c#L33-L35).
It's noted in the code docs (https://github.com/python/cpython/blob/v3.8.1/Modules/_collectionsmodule.c#L1101-L1107) that insert is implemented in terms of rotate (i.e. insert at index n is equivalent to rotate(-n), appendLeft, rotate(n)). In general, this is O(n). While insertion at a node is O(1), traversing the list to find that node is O(n), so insertion in a deque in general is O(n)
https://docs.python.org/3.8/library/collections.html#deque-objects
Literally in the docs. O(n) time complexity.