4 ms·
So this is like the rest and spread operator in javascript (`...`). An interesting observation is that while python has separate operators for lists ( * ) and
by runarberg 8y ago
So this is like the rest and spread operator in javascript (`...`).
An interesting observation is that while python has separate operators for lists ( * ) and dictionaries ( * * )—javascript has only `...`.
> You need to be careful when using multiple times though. Functions in Python can’t have the same keyword argument specified multiple times, so the keys in each dictionary used with must be distinct or an exception will be raised.
This is not an issue in javascript, the unpacked object with repeated keys takes the value of the last one.
{...{a: 1}, ...{a: 2}}
// => {a: 2}
edit: formatting
- reificator 8y agoLooks like you lost some characters to HN's pseudo-markdown.
- the_clarence 8y agoSame with Golang: A := []int{1,2} B := append(A, A...) fmt.Println(B) > [1, 2, 1, 2]
- ereyes01 8y agoGolang has no equivalent to double-* since it doesn't do keyword arguments.
- masklinn 8y agoNeither does javascript, "keyword expansion" only occurs for object literals (which is why it's unambiguous: objects can't be created from sequences and don't implement the iteration protocol, so expansion within an object context can easily be special-cased).
- jacobolus 8y agoYes, the Python feature is much older. From what I can tell, Python inspired Ruby, Ruby inspired CoffeeScript, and CoffeeScript inspired JavaScript to adopt this feature.
- kroltan 8y agoI suppose both observations are reminiscent of the fact that Python has language-level support for named parameters. Given that named and sequential parameters are treated differently everywhere in Python (sequential params must be provided, keyword args are optional, amongst other things), it would be extremely surprising behaviour if the run-time type of the value being spread determined what kind of spread happened. In JavaScript, the surrounding syntatical context solely decides if it's an object or array splat. But since Python has 2 kinds of parameters, to preserve obviousness when reading code using splats, they went with 2 operators for each parameter kind, and then separated list and dictionary splat analogously.
- int_19h 8y ago> it would be extremely surprising behaviour if the run-time type of the value being spread determined what kind of spread happened. The other reason to distinguish * and double-* is because * works with any iterable, and dicts are themselves iterables (of their keys). So you can actually use * on dicts, it just does something different: >>> d = {'a': 1, 'b' : 2} >>> [*d] ['a', 'b'] You could arguably say that only * makes sense here since it's a list context. But then, as you say, function calls would still be ambiguous because they support both positional and named arguments. This keeps it all unambiguously consistent in all contexts.
- th 8y agoIt's also not an issue in Python's dictionary literal syntax: >>> {{'a': 1}, {'a': 2}} {'a': 2} So the multiple keyword argument problem isn't an inherent issue with so much as it's a problem with keyword arguments being specified twice (which has been a restriction since before they allowed multiple to be used).