heapq module contains all the function to implement a Heap structure,
Main functions required to implement Heap data structure are:
function heappush - to push an element in Heap
function heappop - to pop an element from Heap
for implementing Minheap this functions are present in the module as :
heappush - for adding element into Minheap
heappop - to pop an element from Minheap
for implementing Maxheap only one of this two required functions is present:
_heappop_max - to pop an element …
[View More]from Maxheap
I suggest adding a Maxheap version of heappush into heapq module.
_heappush_max - for adding an element into Maxheap.
Comments are welcome.
[View Less]
I would like to propose dict (or mapping) unpacking assignment. This is
inspired in part by the Python-Ideas thread "f-strings as assignment
targets", dict unpacking in function calls, and iterable unpacking
assignment.
Comments welcome.
Background
----------
Iterable unpacking assignment:
values = (1, 2, 3)
a, b, c = *values
is a very successful and powerful technique in Python. Likewise dict
unpacking in function calls and dict displays:
kwargs = {'a': 1, 'b': 2}
…
[View More]func(**kwargs)
d = {**kwargs, 'c': 3}
There have been various requests for allowing dict unpacking on the
right-hand side of an assignment [citation required] but in my opinion
none of them have had a good justification.
Motivated by the idea of scanning text strings with a scanf-style
function, I propose the following behaviour for dict unpacking
assignment:
items = {'eggs': 2, 'cheese': 3, 'spam': 1}
spam, eggs, cheese = **items
assert spam == 1 and eggs == 2 and cheese == 3
Syntax
------
target_list [, **target] = **expression
`target_list` is a comma-separated list of targets. Targets may be:
- simple names, e.g. `spam` and `eggs`
- dotted names, e.g. `spam.eggs`
- numbered subscripts, e.g. `spam[1]`
but is not required to support arbitrary complex targets such as:
spam(*args).eggs(2*x + y)[1].cheese # not supported
Likewise only int literals are supported for subscripts. (These
restrictions may be lifted.)
This is similar to the limited range of fields acceptabled by the string
format mini-language. The same restrictions apply to `**target`.
Each target must be unique.
`expression` must evaluate to a dict or other mapping.
Assignment proceeds by matching up targets from the left to keys on the
right:
1. Every target must be matched exactly by a key. If there is a target
without a corresponding key, that is an error.
2. Any key which does not match up to a target is an error, unless a
`**target` is given.
3. If `**target` is given, it will collect any excess key:value pairs
remaining into a dict.
4. If the targets and keys match up, then the bindings are applied from
left to right, binding the target to the value associated with that key.
Examples:
# Targets are not unique
a, b, a = **items
=> SyntaxError
# Too many targets
a, b, c = **{'a': 1, 'b': 2}
=> raises a runtime exception
# Too few targets
a = **{'a': 1, 'b': 2}
=> raises a runtime exception
a, **extras = **{'a': 1, 'b': 2}
assert a == 1
assert extras == {'b': 2}
# Equal targets and keys
a, b, **extras = **{'a': 1, 'b': 2}
assert a == 1
assert b == 2
assert extras == {}
# Dotted names
from types import SimpleNamespace
obj = SimpleNamespace()
obj.spam = **{'obj.spam': 1}
assert obj.spam == 1
# Subscripts
arr = [None]*5
arr[1], arr[3] = **{'arr[3]': 33, 'arr[1]': 11}
assert arr == [None, 11, None, 33, None]
Assignments to dotted names or subscripts may fail, in which case the
assignment may only partially succeed:
spam = 'something'
eggs = None
spam, eggs.attr = {'spam': 1, 'eggs.attr': 2}
# raises AttributeError: 'NoneType' object has no attribute 'attr'
# but `spam` may have already been bound to 1
(I think that this is undesirable but unavoidable.)
Motivating use-cases
--------------------
The motivation comes from the discussion for scanf-like functionality.
The addition of dict unpacking assignment would allow something like
this:
pattern = "I'll have {main} and {extra} with {colour} coffee."
string = "I'll have spam and eggs with black coffee."
main, extra, colour = **scanf(pattern, string)
assert main == 'spam'
assert extra == 'eggs'
assert colour == 'black'
But the possibilities are not restricted to string scanning. This will
allow functions that return multiple values to choose between returning
them by position or by name:
height, width = get_dimensions(window) # returns a tuple
height, width = **get_dimensions(window) # returns a mapping
Developers can choose whichever model best suits their API.
Another use-case is dealing with kwargs inside functions and methods:
def method(self, **kwargs):
spam, eggs, **kw = **kwargs
process(spam, eggs)
super().method(**kw)
--
Steve
[View Less]