🥰beauty of python
Python is the best language for interview
🥰 beauty_of_python
Collections
data type
Original
Improved
priorityQueue
heapq.* methods
SortedList
list / stack / queue
[]
deque
deque
dictionary
dict
defaultdict
Compare heapq and SortedList complexity - TODO
Sort comparator - TODO
Pass comparator to Sorted() and sort()
Pass comparator to SortedContainers
Swap variables
Repeat strings
Type conversions
int and char
ord: int to char
char: char to int
f-string
Walrus operator :=
used in assignment expressions
Used in list comprehension
Decorator
the mechanism behind @lru_cache
Slicing
The result of slicing a list is a whole new list. References to the ojbects from the original list are maintained.
Assigning to a list slice will replace that range in the original sequence with what's referenced even if their lengths are different.
Slicing is forgiving of start or end indexes that are out of bounds, making it easy to express slices on the front or back boundaries of a sequence (like a[:20] or a[-20:]).
Stride syntax
somelist[start🔚stride]
Prefer to use positive stride values in slices without start or end indexes. Avoid negative stride values if possible.
List comprehension
List comprehensions allow you to create a new list from an existing one.
List comprehensions are clearer than the map and filter because they don't require lambda expressions.
List comprehensions allow you to easily skip items from the input list, a behavior map doesn't support without help from filter.
Dictionaries and sets also support comprehension expressions.
Number of expressions
If the expression included another loop, the list comprehension would get so long that you'd have to split it over multiple lines.
List comprehensions also support multiple if conditions.
Generator expressions
The problem with list comprehension is that they may create a whole new list containing one item for each value in the input sequence. This is fine for small inputs, but for large inputs this could consume significant amounts of memory.
Yield
yield keyword returns a generator that could be iterated upon.
What the yield keyword does is as follows: Each time you iterate, Python runs the code until it encounters a yield statement inside the function. Then, it sends the yielded value and pauses the function in that state without exiting. When the function is invoked the next time, the state at which it was last paused is remembered and execution is continued from that point onwards. This continues until the generator is exhausted.
How is it different from return keyword: Had you used return in place of yield, the function would have returned the respective value, all the local variable values that the function had earlier computed would be cleared off and the next time the function is called, the function execution will start fresh.
Yield from
Example
Iterator
Iterables
Enumerate over range
Prefer Enumerate instead of range to index into a sequence.
You can supply a second parameter to enumerate to specify the number from which to begin counting.
Zip for iterators in parallel
The zip built-in function can be used to iterate over multiple iterators in parallel.
In Python 3, zip is a lazy generator that produces tuples.
Star + zip
References
Effective Python: 59 Ways to write better Python code
Last updated