digitalmars.D.learn - How to imporve D-translation of these Python list comprehensions ?
- xenon325 (104/104) Jan 15 2018 A workmate has recently shown this piece of code to show how nice
- Igor Shirkalin (3/10) Jan 15 2018 This is the most terrible Python code I have ever seen.
- Russel Winder (14/22) Feb 01 2018 Actually I have seen worse, but=E2=80=A6 I think the way this Python cod...
- lobo (6/9) Jan 15 2018 Well if that is what they can do in Python I'd hate to see their
- Russel Winder (13/24) Feb 01 2018 Apart from the slur on Perl, I have to agree with this. Using a
- bauss (2/20) Feb 01 2018 I'd be interested in seeing the result.
- Biotronic (37/40) Jan 15 2018 I will admit clarity has suffered, but I like the brevity:
- Timon Gehr (26/33) Jan 15 2018 import std.stdio, std.algorithm, std.range, std.array, std.conv,
- Timon Gehr (22/27) Jan 15 2018 Actually, better to use std.array.assocArray.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (7/13) Feb 01 2018 But that was really verbose, why didn't he contract everything
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (10/24) Feb 01 2018 Rewritten in without comprehensions it is something like:
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
Jan 15 2018
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
Jan 15 2018
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:Actually I have seen worse, but=E2=80=A6 I think the way this Python code i= s 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. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Road m: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.ukA workmate has recently shown this piece of code to show how=20 nice Python is (we are mostly C and growing C++ shop): dd =3D [dict(_name=3Dk, **{a + str(i): aget(d, k, a) for a in=20 aa for i, d in enumerate([srv1, srv2])}) for k in sorted(kk)]=20 This is the most terrible Python code I have ever seen. If you know Python, could you please unroll to more readable form?
Feb 01 2018
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" :)
Jan 15 2018
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: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. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Road m: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.ukA workmate has recently shown this piece of code to show how=20 nice Python is (we are mostly C and growing C++ shop): =20 [...]=20 Well if that is what they can do in Python I'd hate to see their=20 C++! They have done a great job making Python code read like=20 Perl. This looks like something you'd see in an assignment at=20 uni; "Decipher this Python code and port to your language of=20 choice" :)
Feb 01 2018
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:I'd be interested in seeing the result.On Monday, 15 January 2018 at 19:05:52 UTC, xenon325 wrote: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.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" :)
Feb 01 2018
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
Jan 15 2018
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; }
Jan 15 2018
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; }
Jan 15 2018
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())))] :*)
Feb 01 2018
On Thursday, 1 February 2018 at 20:18:37 UTC, Ola Fosheim Grøstad wrote:On Monday, 15 January 2018 at 19:05:52 UTC, xenon325 wrote:Rewritten in without comprehensions it is something like: dd = [] for k in sorted(set(chain(srv1.keys(), srv2.keys()))): record = {'_name':k} for a in 'ver','rev': for i, d in enumerate((srv1, srv2)): record[f'{a}{i}'] = d.get(k,{}).get(a,'') dd.append(record)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())))] :*)
Feb 01 2018