Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 15, 2018 How to imporve D-translation of these Python list comprehensions ? | ||||
---|---|---|---|---|
| ||||
A workmate has recently shown this piece of code to show how nice Python is (we are mostly C and growing C++ shop): import json from itertools import chain srv1 = {'acs': {'ver': '1.2.3', 'rev': '6f2260d'}, 'cms': {'ver': '4.5', 'rev': 'b17a67e'}, 'ots': {'ver': '6.7.80', 'rev': '4f487d2'}} srv2 = {'acs': {'ver': '1.2.3', 'rev': '6f2260d'}, 'cms': {'ver': '5.1', 'rev': '2a56c53'}, 'vaa': {'ver': '0.7', 'rev': '00852cb'}} def aget(d, k1, k2): return d.get(k1, {}).get(k2, '') aa = ['ver', 'rev'] kk = set(chain(srv1.keys(), srv2.keys())) dd = [dict(_name=k, **{a + str(i): aget(d, k, a) for a in aa for i, d in enumerate([srv1, srv2])}) for k in sorted(kk)] print(json.dumps(dd, indent=2, sort_keys=True)) Output is: [ { "_name": "acs", "rev0": "6f2260d", "rev1": "6f2260d", "ver0": "1.2.3", "ver1": "1.2.3" }, { "_name": "cms", "rev0": "b17a67e", "rev1": "2a56c53", "ver0": "4.5", "ver1": "5.1" }, { "_name": "ots", "rev0": "4f487d2", "rev1": "", "ver0": "6.7.80", "ver1": "" }, { "_name": "vaa", "rev0": "", "rev1": "00852cb", "ver0": "", "ver1": "0.7" ] } Another coworker replied with Scala equivalent. So I thought, why wouldn't I join the party and translate that to D :) My best take so far is (with some D-intro comments https://run.dlang.io/is/GxsauU): import std.stdio; import std.algorithm; import std.range; import std.array; import std.conv; import std.json; void main() { // not `immutable` to describe one less thing const srv1 = [ "acs": ["ver": "1.2.3", "rev": "6f2260d"], "cms": ["ver": "4.5", "rev": "b17a67e"], "ots": ["ver": "6.7.80", "rev": "4f487d2"]]; const srv2 = [ "acs": ["ver": "1.2.3", "rev": "6f2260d"], "cms": ["ver": "5.1", "rev": "2a56c53"], "vaa": ["ver": "0.7", "rev": "00852cb"]]; string[string][] result; chain(srv1.keys, srv2.keys) .sort .uniq .each!( (uniqComp) { auto verInfo = ["_name": uniqComp]; [srv1, srv2] .enumerate .each!( serv => ["ver", "rev"].each!( prop => verInfo[prop ~ serv.index.to!string] = serv.value.get(uniqComp, ["": ""]).get(prop, "")) ); /+ // The same as above and I like this better, actually foreach(servIdx, serv; [srv1, srv2].enumerate){ foreach(prop; ["ver", "rev"]) verInfo[prop ~ servIdx.to!string] = serv.get(uniqComp, ["": ""]).get(prop, ""); } +/ result ~= verInfo; }); writeln("---"); writeln(JSONValue(result).toPrettyString()); writeln("---"); } I think, most clear code would be with tripple `foreach`, so I'll go with that. But probably someone will come up with something better and range-ier. Suggestion are welcome! --- Alexander |
January 15, 2018 Re: How to imporve D-translation of these Python list comprehensions ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to xenon325 | On Monday, 15 January 2018 at 19:05:52 UTC, xenon325 wrote: > A workmate has recently shown this piece of code to show how nice Python is (we are mostly C and growing C++ shop): > dd = [dict(_name=k, **{a + str(i): aget(d, k, a) for a in aa for i, d in enumerate([srv1, srv2])}) for k in sorted(kk)] This is the most terrible Python code I have ever seen. If you know Python, could you please unroll to more readable form? > Suggestion are welcome! > > --- > Alexander |
January 15, 2018 Re: How to imporve D-translation of these Python list comprehensions ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to xenon325 | On Monday, 15 January 2018 at 19:05:52 UTC, xenon325 wrote:
> A workmate has recently shown this piece of code to show how nice Python is (we are mostly C and growing C++ shop):
>
> [...]
Well if that is what they can do in Python I'd hate to see their C++! They have done a great job making Python code read like Perl. This looks like something you'd see in an assignment at uni; "Decipher this Python code and port to your language of choice" :)
|
January 15, 2018 Re: How to imporve D-translation of these Python list comprehensions ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to xenon325 | On Monday, 15 January 2018 at 19:05:52 UTC, xenon325 wrote: > I think, most clear code would be with tripple `foreach`, so I'll go with that. But probably someone will come up with something better and range-ier. I will admit clarity has suffered, but I like the brevity: import std.json : JSONValue; import std.array : array, assocArray; import std.range : enumerate, byPair; import std.algorithm : sort, joiner, map, uniq, each; import std.typecons : tuple; import std.conv : to; import std.stdio : writeln; unittest { immutable srv1 = ["acs": ["ver": "1.2.3", "rev": "6f2260d"], "cms": ["ver": "4.5", "rev": "b17a67e"], "ots": ["ver": "6.7.80", "rev": "4f487d2"]]; immutable srv2 = ["acs": ["ver": "1.2.3", "rev": "6f2260d"], "cms": ["ver": "5.1", "rev": "2a56c53"], "vaa": ["ver": "0.7", "rev": "00852cb"]]; immutable keys = ["rev", "ver"]; immutable srvs = [srv1, srv2]; alias aget = (name, key) => srvs.map!(s => s.get(name, [key:""])[key]); alias bget = (name, key) => aget(name, key).enumerate.map!(b => tuple(key~b.index.to!string, b.value)); alias merge = (aa1, aa2) => (aa2.byPair.each!(kv => aa1[kv.key] = kv.value), aa1); auto result = srvs .map!(s => s.byKey) .joiner .array .sort .uniq .map!(name => merge(keys.map!(key => bget(name, key)).joiner.assocArray, ["_name": name])) .array; writeln(JSONValue(result).toPrettyString()); } -- Simen |
January 15, 2018 Re: How to imporve D-translation of these Python list comprehensions ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to xenon325 | On 15.01.2018 20:05, xenon325 wrote: > > > I think, most clear code would be with tripple `foreach`, so I'll go with that. But probably someone will come up with something better and range-ier. > > Suggestion are welcome! import std.stdio, std.algorithm, std.range, std.array, std.conv, std.json, std.typecons; auto aa(R)(R r){ typeof(r.front[1])[typeof(r.front[0])] a; foreach(x;r) a[x[0]] = x[1]; return a; } alias emap(alias a) = map!(x => a(x.expand)); void main(){ auto srv1 = [ "acs": ["ver": "1.2.3", "rev": "6f2260d"], "cms": ["ver": "4.5", "rev": "b17a67e"], "ots": ["ver": "6.7.80", "rev": "4f487d2"]]; auto srv2 = [ "acs": ["ver": "1.2.3", "rev": "6f2260d"], "cms": ["ver": "5.1", "rev": "2a56c53"], "vaa": ["ver": "0.7", "rev": "00852cb"]]; chain(srv1.keys, srv2.keys).sort.uniq .map!(k => chain(only(tuple("_name", k)), cartesianProduct(only("ver", "rev"), only(srv1, srv2).enumerate) .emap!((prop, srv) => tuple(text(prop, srv.index), srv.value.get(k, null).get(prop, ""))) ).aa).array.JSONValue.toPrettyString.writeln; } |
January 15, 2018 Re: How to imporve D-translation of these Python list comprehensions ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 15.01.2018 22:51, Timon Gehr wrote: > auto aa(R)(R r){ > typeof(r.front[1])[typeof(r.front[0])] a; > foreach(x;r) a[x[0]] = x[1]; > return a; > } Actually, better to use std.array.assocArray. import std.stdio, std.algorithm, std.range, std.array, std.conv, std.json, std.typecons; alias emap(alias a) = map!(x => a(x.expand)); void main(){ auto srv1 = [ "acs": ["ver": "1.2.3", "rev": "6f2260d"], "cms": ["ver": "4.5", "rev": "b17a67e"], "ots": ["ver": "6.7.80", "rev": "4f487d2"]]; auto srv2 = [ "acs": ["ver": "1.2.3", "rev": "6f2260d"], "cms": ["ver": "5.1", "rev": "2a56c53"], "vaa": ["ver": "0.7", "rev": "00852cb"]]; chain(srv1.keys, srv2.keys).sort.uniq .map!(k => chain(only(tuple("_name", k)), cartesianProduct(only("ver", "rev"), only(srv1, srv2).enumerate) .emap!((prop, srv) => tuple(text(prop, srv.index), srv.value.get(k, null).get(prop, ""))) ).assocArray).array.JSONValue.toPrettyString.writeln; } |
February 01, 2018 Re: How to imporve D-translation of these Python list comprehensions ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Igor Shirkalin Attachments:
| On Mon, 2018-01-15 at 20:27 +0000, Igor Shirkalin via Digitalmars-d- learn wrote: > On Monday, 15 January 2018 at 19:05:52 UTC, xenon325 wrote: > > A workmate has recently shown this piece of code to show how > > nice Python is (we are mostly C and growing C++ shop): > > dd = [dict(_name=k, **{a + str(i): aget(d, k, a) for a in > > aa for i, d in enumerate([srv1, srv2])}) for k in sorted(kk)] > > This is the most terrible Python code I have ever seen. > If you know Python, could you please unroll to more readable form? Actually I have seen worse, but… I think the way this Python code is presented is fairly dreadful. I am fiddling with trying to provide a better version. If people are interested in this I can share in a while when it's ready. -- Russel. =========================================== Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Road m: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk |
February 01, 2018 Re: How to imporve D-translation of these Python list comprehensions ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to lobo Attachments:
| On Mon, 2018-01-15 at 21:13 +0000, lobo via Digitalmars-d-learn wrote: > On Monday, 15 January 2018 at 19:05:52 UTC, xenon325 wrote: > > A workmate has recently shown this piece of code to show how nice Python is (we are mostly C and growing C++ shop): > > > > [...] > > Well if that is what they can do in Python I'd hate to see their C++! They have done a great job making Python code read like Perl. This looks like something you'd see in an assignment at uni; "Decipher this Python code and port to your language of choice" :) Apart from the slur on Perl, I have to agree with this. Using a dreadful bit of Python code is the start of a downward spiral of expectation and programming in other languages. As noted earlier, I am working on a nicer rendering of this algorithm, and will be happy to share if people are interested. -- Russel. =========================================== Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Road m: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk |
February 01, 2018 Re: How to imporve D-translation of these Python list comprehensions ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Russel Winder | On Thursday, 1 February 2018 at 11:59:23 UTC, Russel Winder wrote:
> On Mon, 2018-01-15 at 21:13 +0000, lobo via Digitalmars-d-learn wrote:
>> On Monday, 15 January 2018 at 19:05:52 UTC, xenon325 wrote:
>> > A workmate has recently shown this piece of code to show how nice Python is (we are mostly C and growing C++ shop):
>> >
>> > [...]
>>
>> Well if that is what they can do in Python I'd hate to see their C++! They have done a great job making Python code read like Perl. This looks like something you'd see in an assignment at uni; "Decipher this Python code and port to your language of choice" :)
>
> Apart from the slur on Perl, I have to agree with this. Using a dreadful bit of Python code is the start of a downward spiral of expectation and programming in other languages.
>
> As noted earlier, I am working on a nicer rendering of this algorithm, and will be happy to share if people are interested.
I'd be interested in seeing the result.
|
February 01, 2018 Re: How to imporve D-translation of these Python list comprehensions ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to xenon325 | On Monday, 15 January 2018 at 19:05:52 UTC, xenon325 wrote:
> def aget(d, k1, k2):
> return d.get(k1, {}).get(k2, '')
>
> aa = ['ver', 'rev']
> kk = set(chain(srv1.keys(), srv2.keys()))
> dd = [dict(_name=k, **{a + str(i): aget(d, k, a) for a in aa for i, d in enumerate([srv1, srv2])}) for k in sorted(kk)]
But that was really verbose, why didn't he contract everything into one line?
dd = [dict(_name=k, **{a + str(i): d.get(k,{}).get(a,'') for a in ('ver','rev') for i, d in enumerate((srv1, srv2))}) for k in sorted(set(chain(srv1.keys(), srv2.keys())))]
:*)
|
Copyright © 1999-2021 by the D Language Foundation