These are also easier to read and write than the Python version, as you can just follow the dataflow from top to bottom (or left to right if it fits into a single line). In Python, your eyes have to jump around to find where to the next bit of processing happens, not just in comprehensions but also with map/filter/list/len and co which are freestanding functions for some reason.
“You can…”
Sure, but the Python code is so much nicer.
I don’t even like Python all that much but it’s comprehensions and generators are very sweet.
I find the non-Python versions easier to read, since they show the exact data flow in order (instead of Python’s [3 for 1 if 2] order) and they allow more advanced scenarios.
Sure you can do that and I use things like this all the time in other languages, but the python example was very basic. There are other cases that are sometimes harder to reproduce e.g. when iterating over dictionaries to create a list, when you have tuples etc.
It's the opposite, I feel. When the cases are not basic, the python way gets even messier. Or do you have any examples?
All Python list comprehensions do is [(expression involving foo's) for foo0, …, fooN in (iterable) if (expression involving foo's that should return a boolean-ish value)]. Nothing more, nothing less. Nothing that can’t be expressed by filter-then-map.
So, given the dictionary {"a": 1, "b": 4, "c": 2}, if you want ["b=4", "c=2"], you can do this in Python:
d = {"a": 1, "b": 4, "c": 2}
l = [f"{k}={v}" for k, v in d.items() if v % 2 == 0] # replace [] with () if you want a generator instead of a list
Or this in C#: var d = new Dictionary<string, int> { {"a", 1}, {"b", 4}, {"c", 2} };
var l = d
.Where(pair => pair.Value % 2 == 0)
.Select(pair => $"{pair.Key}={pair.Value}")
.ToList(); // remove this if you want an IEnumerable<string> instead of a List<string>
The Python version has tuple unpacking, whereas the C# version iterates over KeyValuePair<TKey,TValue>. Slightly more typing, and perhaps slightly less ideal if you’re dealing with tuples without field names, but still pretty readable. The C# solution is also more obvious about the execution order.And if you want to sort the output by the dictionary value?
l = [f"{k}={v}" for k, v in sorted(d.items(), key=lambda kv: kv[1]) if v % 2 == 0]
# 5 3 2 1 2a 4 <- Execution order
var l = d // Execution order: 1
.OrderBy(pair => pair.Value) // 2
.Where(pair => pair.Value % 2 == 0) // 3
.Select(pair => $"{pair.Key}={pair.Value}") // 4
.ToList(); // 5
And if you like Python’s dictionary comprehensions:
you can use ToDictionary in C#: