6 ms·
As a python veteran, I'm quite envious of the advanced destructuring you get in some languages. Unpacking doesn't let you specify default values if cardinality
by BiteCode_dev 4y ago
As a python veteran, I'm quite envious of the advanced destructuring you get in some languages.
Unpacking doesn't let you specify default values if cardinality doesn't match, nor can you extract dictionaries by keys.
Since operators.itemgetter and itertools.slice are limited, I end up either adding a dependency or reinventing the wheel for every project.
- d0mine 4y agothere is a pattern matching in Python 3.10 (match/case) which can match dictionaries. https://peps.python.org/pep-0636/#going-to-the-cloud-mappings https://peps.python.org/pep-0636/#going-to-the-cloud-mapping...
- BiteCode_dev 4y agoYes, but since it's an expression it is very verbose for a simple assignment. Python really needs something like: {foo: "default", mapping} = mapping
- d0mine 4y agoYou might want: foo = mapping.pop("foo", "default") It removes "foo" key from mapping if any. `foo` is "default" if "foo" is missing and `mapping["foo"]` otherwise. Dictionary unpacking compatible with the match/case syntax could look like: {"foo": foo, **rest} = mapping It asserts that there is "foo" key in mapping and puts its value into `foo`.
- deleted 4y ago[deleted]
- z3c0 4y ago> Unpacking doesn't let you specify default values if cardinality doesn't match, nor can you extract dictionaries by keys. I'm a bit confused by this one, but maybe I'm misunderstanding. Does this not accomplish what you're defining? def parse_record(first=0, second=1, **all_the_others) -> dict: return dict(first=first, second=second, **all_the_others) dictionary = dict(first=99, third=2) parse_record(**dictionary) > {"first": 99, "second": 1, "third": 2}
- bjourne 4y agoThat's packing. Unpacking would be something like this: d = {'a' : 10, 'b' : 20, 'c' : 30} {'a' : v1, 'b' : v2, **others} = d print(v1, v2, others) # prints 10, 20, {'c' : 30}
- BiteCode_dev 4y agoExactly. The working code in Python, as a function, would be: def extract(mapping, *args, **kwargs): for a in args: yield mapping[a] for key, default in kwargs.items(): yield mapping.get(key, default)
- deleted 4y ago[deleted]
- bmitc 4y ago> Unpacking doesn't let you specify default values if cardinality doesn't match Functional languages that have pattern matching have wildcard matches that allow you to explicitly handle things that don't match as expected and also have tail matching for lists. > nor can you extract dictionaries by keys I'm not exactly sure what you mean here, but you can definitely do that for records in F# and maps/structs in Elixir. It's done all the time.
- bobbylarrybobby 4y agoI think the parent comment is referring to how you can do e.g., `let {x, y, z} = point` (JS, object/dictionary) or `let Point {x, y, z} = point} (Rust, struct) but in Python your only option is `x = point.x; y = point["y"]` etc
- BiteCode_dev 4y agoIndeed. Now you can do: import operator foo, bar, baz = operator.itemgetter('foo', 'bar', 'baz')(mapping) But it's verbose, inelegant, and doesn't handle missing values.
- bmitc 4y agoI misread their first sentence. I see now that they’re lamenting what I mentioned not being in Python. I was thinking they meant in general and not just in Python.
- lysecret 4y agoThis is what i liked most working a bit in JS. How you can deconstruct, even in the function definition!!! Using {}. Why did they have to use that for sets in python ahhh. Also using ? For attributes that might be there and being able to chain that is sooo awesome. These two things make for example working with nested Json in JS so much better than in Python.
- BiteCode_dev 4y agoThe ? attribute would indeed be a welcome addition, but not to work in the same way as in JS. In JS, it ignore null values. That wouldn't work in python. We would need a ? to says "ignore AttributeError, IndexError and KeyError on that access". However, the use of {} for set is not a problem. First, remember than Python is much, much older than JS. Insight is 20/20. Second, you could always use a different syntax.