It's O(n), also check out: http://wiki.python.org/moin/TimeComplexity
Answer from Zach Kelling on Stack OverflowThis page documents the time-complexity (aka "Big O" or "Big Oh") of various operations in current CPython. Other Python implementations (or older or still-under development versions of CPython) may have slightly different performance characteristics. However, it is generally safe to assume that they are not slower by more than a factor of O(log n)...
It's O(n), also check out: http://wiki.python.org/moin/TimeComplexity
This page documents the time-complexity (aka "Big O" or "Big Oh") of various operations in current CPython. Other Python implementations (or older or still-under development versions of CPython) may have slightly different performance characteristics. However, it is generally safe to assume that they are not slower by more than a factor of O(log n)...
According to said documentation:
list.index(x)Return the index in the list of the first item whose value is x. It is an error if there is no such item.
Which implies searching. You're effectively doing x in s but rather than returning True or False you're returning the index of x. As such, I'd go with the listed time complexity of O(n).
Time complexity is O(n) . Have a look at the link
http://wiki.python.org/moin/TimeComplexity
It's O(n), also check out: http://wiki.python.org/moin/TimeComplexity
This page documents the time-complexity (aka "Big O" or "Big Oh") of various operations in current CPython. Other Python implementations (or older or still-under development versions of CPython) may have slightly different performance characteristics. However, it is generally safe to assume that they are not slower by more than a factor of O(log n)..
The problem you have in your current methods is that you make placing one element dependent on the entire opposing list. Instead, simply make a chart of where each element is in each list.
Use a dict. Go through list1, filling in key:value to be the element and its index. This gives you
{ 5: 0, 8: 1, 1: 2, 4: 3 }
Now, go through list 2. Access each element; if it exists (use get for the fail-safe functionality), print the stored index (list1) and the current index (list2). If it doesn't exist, then simply skip printing.
O(N) complexity.
If this is the code:
for searched in first: # O(n)
i = second.index(searched) # O(m)
print(i)
Then the answer is O(n * m), where n = len(first), m = len(second).
It can be done in O(n + m) if you use dictionaries.
Accessing any array element is in constant time, since it is a known by memory location (i.e. a pointer.)
The array does not need to go through prior elements in order to access the nth element (i.e. it is not like a linked list.) The location of all elements is known before hand and can simply be accessed directly.
Updated thanks to comments.
array[-x] is syntactic sugar for array[len(lst) - x]. So it's still a simple constant access to a pointer and takes no time.
You can see this answer for a bit more info. While it is about C, the concepts should be the same.
Native Python lists are arrays of pointers and accessing any element is O(1).
Note that this is an implementation detail specific to the standard Python implementation, known as CPython. Other language implementations may implement lists differently.
Python does not iterate through lists to find a particular index. Lists are arrays (of pointers to elements) in contiguous memory and so locating the desired element is always a simple multiplication and addition. If anything, list[-1] will be slightly slower because Python needs to add the negative index to the length to get the real index. (I doubt it is noticeably slower, however, because all that's done in C anyway.)
Why not test and see?
import timeit
t=timeit.timeit('mylist[99]',setup='mylist=list(range(100))',number=10000000)
print (t)
t=timeit.timeit('mylist[-1]',setup='mylist=list(range(100))',number=10000000)
print (t)
Of course, as you can see by running this a couple times, there's really no (noticable) difference for the reasons pointed out in the other answers.
there is a very detailed table on python wiki which answers your question.
However, in your particular example you should use enumerate to get an index of an iterable within a loop. like so:
for i, item in enumerate(some_seq):
bar(item, i)
The answer is "undefined". The Python language doesn't define the underlying implementation. Here are some links to a mailing list thread you might be interested in.
It is true that Python's lists have been implemented as contiguous vectors in the C implementations of Python so far.
I'm not saying that the O() behaviours of these things should be kept a secret or anything. But you need to interpret them in the context of how Python works generally.
Also, the more Pythonic way of writing your loop would be this:
def foo(some_list):
for item in some_list:
bar(item)
- filter has O(n) complexity.
- [0..x] has O(n) complexity.
(!!)has O(n) complexity.
Your naive implementation is quadratic due to the nested (!!)
Lists are lazy here, so the filter and list generator have combined O(n) complexity plus some constant per element (with laziness, generation of the list and filtering happen in one pass, effectively).
I.e work on generation and filtering is (O(n+n*k)) on lazy lists, rather than O(2*n) in a strict list, where k is cost of generating a single cons cell.
However, your use of linear indexing makes this quadratic anyway. I note that on strict vectors with fusion this would be O(n+n*j) (linear) due to constant j lookup complexity, or with a log structured lookup, O(n+n*log n).
Linear complexity
positions2 :: Eq a => a -> [a] -> [Int]
positions2 x = map fst . filter ((x==).snd) . zip [0..]
main = print $ positions2 3 [1,2,3,4,1,3,4]
(I suggest to you read and understand how exactly works)
(your code take quadratic time since (!!) take linear time)
Immutability is the answer. This is a simplified version of the implementation of List
trait List[+A] {
def prependA1 >: A: List[A]
}
case class ConsA extends List[A] {
def prependA1 >: A: List[A1] = Cons(a, this)
}
case object Nil extends List[Nothing] {
def prependA1 >: A: List[A1] = Cons(a, Nil)
}
With this ADT you are able to prepend but not create a double linked list. Let's se an example
val list1 = Cons(1, Cons(2, Nil))
val list2 = Cons(0, list1)
val list3 = Cons(-1, list1)
This can not be implemented as a doublylinked list without mutating the value of list1 when you create list2 and list3
For most cases you should be using a Vector instead of a List. Here is a performance comparison for different Scala collections:
http://docs.scala-lang.org/overviews/collections/performance-characteristics.html
Get item is getting an item in a specific index, while lookup means searching if some element exists in the list. To do so, unless the list is sorted, you will need to iterate all elements, and have O(n) Get Item operations, which leads to O(n) lookup.
A dictionary is maintaining a smart data structure (hash table) under the hood, so you will not need to query O(n) times to find if the element exists, but a constant number of times (average case), leading to O(1) lookup.
Accessing a list l at index n l[n] is O(1) because it is not implemented as a Vanilla linked list where one needs to jump between pointers (value, next-->) n times to reach cell index n.
If the memory is continuous and the entry size would had been fixed, reaching a specific entry would be trivial as we know to jump n times an entry size (like classic arrays in C).
However, since list is variable in entries size, the python implementation uses a continuous memory list just for the pointers to the values. This makes indexing a list (l[n]) an operation whose cost is independent of the size of the list or the value of the index.
For more information see: FAQ, variable-length array (VLA) & Dynamic array
Information on this topic is now available on Wikipedia at: Search data structure
+----------------------+----------+------------+----------+--------------+
| | Insert | Delete | Search | Space Usage |
+----------------------+----------+------------+----------+--------------+
| Unsorted array | O(1) | O(1) | O(n) | O(n) |
| Value-indexed array | O(1) | O(1) | O(1) | O(n) |
| Sorted array | O(n) | O(n) | O(log n) | O(n) |
| Unsorted linked list | O(1)* | O(1)* | O(n) | O(n) |
| Sorted linked list | O(n)* | O(1)* | O(n) | O(n) |
| Balanced binary tree | O(log n) | O(log n) | O(log n) | O(n) |
| Heap | O(log n) | O(log n)** | O(n) | O(n) |
| Hash table | O(1) | O(1) | O(1) | O(n) |
+----------------------+----------+------------+----------+--------------+
* The cost to add or delete an element into a known location in the list
(i.e. if you have an iterator to the location) is O(1). If you don't
know the location, then you need to traverse the list to the location
of deletion/insertion, which takes O(n) time.
** The deletion cost is O(log n) for the minimum or maximum, O(n) for an
arbitrary element.
I guess I will start you off with the time complexity of a linked list:
Indexing---->O(n)
Inserting / Deleting at end---->O(1) or O(n)
Inserting / Deleting in middle--->O(1) with iterator O(n) with out
The time complexity for the Inserting at the end depends if you have the location of the last node, if you do, it would be O(1) other wise you will have to search through the linked list and the time complexity would jump to O(n).
There is no Java (standard) collection type with that property.
The indexOf(Object) method is declared in List, and there are no List implementations that provide better than O(N) lookup.
There are other collection types that provide O(logN) or O(1) lookup, but they do not return a position (and index) like indexOf(Object) does. (HashMap and HashSet provide respectively get(key) and contains(object) that are O(1).)
If there is nothing, can anyone help me out to deduce the reason why such has not been formed? Any particular reason?
Because a data structure that did provide such functionality would be complicated, and (probably) slower and/or combine the drawbacks of both an ArrayList and a HashMap.
I can't think of a good way to implement a list with fast lookup; i.e. one that didn't have serious drawbacks. And if there was a good way, I would have expected the Java team to know about it ... and to have included it in the Java SE library. This is similar to why there are no general purpose concurrent list types.
I am not saying that it is impossible. I'm saying that if it is possible, nobody has discovered a way to do it. AFAIK.
Designing an general purpose collection type involves compromise. When you optimize for one mode of access, you will often de-optimize for another.
To find the index of an element in a Collection in O(1) you need to be able to directly retrieve the index of the element without searching. A List or an array doesn't allow us to do this (requires O(N)) and a Set is not ordered 1.
We are left with a Map but a Map is a key-value pair.
You can create a map with key as the element and value as the index as an auxiliary data structure to your collection. The downside is you need to update the map when you update your collection (List/Array)
or just use the map and get rid of your collection.
1 indexOf method is on a List and not on Collection.