Python reverse() vs [::-1] slice performance [duplicate] - python

This question already has answers here:
Difference between reverse and [::-1]
(2 answers)
Time complexity of reversed() in Python 3
(1 answer)
Closed last month.
Python provides two ways to reverse a list:
List slicing notation
['a','b','c'][::-1] # ['c','b','a']
Built-in reversed() function
reversed(['a','b','c']) # ['c','b','a']
Are there any relevant differences in implementation/performance, or scenarios when one is preferred over the other?

The slicing operator constructs a new list in memory, which has implications on both memory and runtime.
reversed, on the other hand, returns an iterator which simply yields items one after another from the original list in reversed order. It does not allocate any additional memory.
So if all you're doing is iterating over the list in reverse and there's no need to construct a new (for example if you need to mutate it), then I'd say go for reversed.

Related

Time complexity of converting tuple into a list (vice versa) [duplicate]

This question already has answers here:
Time complexity of casting lists to tuples in python and vice versa
(2 answers)
Closed 1 year ago.
if we are have a list lst = [1,2,3,4] and we convert it to a tuple like this tup = tuple(lst), what will be the time complexity of this code?
It is an O(N) operation, tuple(list) simply copies the objects from the list to the tuple.
so, you can still modify the internal objects(if they are mutable) but you can't add new items to the tuple
The time complexity is O(n) because the underlying operation is simply taking the original numbers and copying the objects into a tuple rather than a list.
Python list time complexity: https://wiki.python.org/moin/TimeComplexity
Operation
Average Case
Amortized Worst Case
Copy
O(n)
O(n)

Python sorted() function space comlexity [duplicate]

This question already has answers here:
What is the space complexity of the python sort?
(2 answers)
Closed 2 years ago.
I know that sort() is O(1) space since the sorting is in place. However, sorted() function returns a new list with sorted elements. Since sorted() returns a new array with sorted elements, does this mean that an algorithm that uses the sorted() function takes O(n) space to execute?
Would sorted() be the same thing as creating an array and copying all elements, then running sort() on that new array?
for i in sorted(some_list):
// do something
sorted() uses Timsort: https://en.wikipedia.org/wiki/Timsort, which has O(n) space complexity.

Why are you unable to print certain iterators like zip or map? [duplicate]

This question already has answers here:
What are iterator, iterable, and iteration?
(16 answers)
Closed 2 years ago.
I came across certain built-in functions such as zip and map.
I tried printing these functions, they resulted as zip object at 0x1007a06c8 or <map object at 0x003AB2E0>.
I understand that these functions return iterators, but I can also use a for loop to run through strings/lists/dicts as iterators. Thus, how are zip and map different, and how I am able to show them? What are some other examples that I should be aware of?
Do something like:
list(zip(a,b))
Explanation:
The zip() function in Python 3 returns an iterator.
The purpose of this is to save memory by only generating the elements of the iterator as you need them, rather than putting it all into memory at once.
You can exhaust it once by doing list(zip(a,b)). So after that anytime you do list(zip(a,b)) would only result in empty list.
zip, map and also range are no collections like lists, strings, sets or dicts, because they are evaluated lazily. This means, that they do not explicitly contain all the values, but only generate the next value when asked to do that (e.g. in a loop or when unpacked in a list).
So lists and maps are iterable, because you can iterate over them, but maps are generators, while lists are containers.
You can unpack generators to a list with list(map(...)) (also works sets or tuples and others), or use the asterisk (*) to unpack them to individual arguments of a function (print(*map(...))).

Itertools Combinations/Permutations size [duplicate]

This question already has answers here:
Is there any built-in way to get the length of an iterable in python?
(10 answers)
What's the shortest way to count the number of items in a generator/iterator?
(7 answers)
Closed 4 years ago.
Is there anyway to see the len() of an itertools.Combination or other object, really, without materializing it to a list?
I can get the cardinality of combs or permutations with the factorials,... but I want something that generalizes.
Thanks
For any iterable it, you can do:
length = sum(1 for ignore in it)
That doesn't create a list, so the memory footprint is small. But for many kinds of iterables, it also consumes it (for example, if it is a generator, it's consumed and can't be restarted; if it is a list, it's not consumed). There is no generally "non-destructive" way to determine the length of an arbitrary iterable.
Also note that the code above will run "forever" if it delivers an unbounded sequence of objects.
No need to create a list. You can count the number of items in an iterable without storing the entire set:
sum(1 for _ in myIterable)
Yes,
def count_iterable(i):
return sum(1 for e in i)
Taken from: Is there any built-in way to get the length of an iterable in python?

.extend() method returning 'None' and not the desired combination of lists I intended it to return [duplicate]

This question already has answers here:
Why do these list operations (methods: clear / extend / reverse / append / sort / remove) return None, rather than the resulting list?
(6 answers)
Closed 5 months ago.
I am playing around with some basic python methods.
Right now I am experimenting with the .extend() method. I basically have two lists and want to combine them into one larger list for demonstration purposes.
This works successfully (successfully as in returning the extended list) in the Shell environment, but not when saving the program. When I want to save the program and run it, it returns the value of 'None'. Any assistance would be greatly appreciated. Thank you.
listOne=[1,2,3]
listTwo=[4,5,6]
listOneandlistTwo=listOne.extend(listTwo)
print(listOneandlistTwo)
listOneandlistTwo=listOne.extend(listTwo)
extend() extends the given list but returns None*, so you have extended listOne with the contents of listTwo and assigned None to listOneandListTwo.
What you want (assuming you want to leave listOne and listTwo as they are) is this:
listOneandlistTwo = listOne + listTwo
* This behavior is by design. If extend() returned the extended list, would it return a copy that's extended? Or would it return the original list extended? It's another detail to remember, so by returning None you are meant to think, "oh, since it's returning None it must be extending the list in place, otherwise it'd be useless."

Categories