Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Am I insane that:

> filtered_temps = { entry["city"]: entry["temp"] for entry in temperatures if entry["temp"] > 20 }

is less readable to me than:

> for _, ct := range temperatures { if ct.Temp > 20 { filteredTemps[ct.City] = ct.Temp } }

??



And all of it is less readable than

    city_temps
      .select { |ct| ct.temp > 20 }
      .to_h   { |ct| [ct.name, ct.temp] }
Or

    let map: HashMap<_, _> = city_temps
      .iter()
      .filter(|ct| ct.temp > 20 )
      .map(|ct| (ct.name, ct.temp) )
      .collect();


There is no need to use anything but filter, like

   filtered_temps = list(filter(lambda e: e["temp"] > 20, temperatures))
IMHO the most readable version (and coincidentally also the shortest).


In the provided example, they’re turning it into a map of city names to temps so I kept that. Yours keeps it as an array of objects with a name and temp.

If you skip that,

    city_temps
      .select { |ct| ct.temp > 20 }
    
    city_temps
      .iter()
      .filter(|ct| ct.temp > 20 )
      .collect();
are still best IMO just due to the natural method chaining of iterators.


Oh, yes, of course you're right, I didn't see that until now - did I say already, that I hate Python's list comprehensions or everything not totally simple?.

So that needs reduce:

    def filter_func(acc, e):
        if e["temp"] > 20:
             acc[e["city"]] = e["temp"]
        return acc

    filtered_temps = functools.reduce(filter_func, temperatures, {})


Technically that's a dict comprehension, not a list comprehension (though they are pretty much the same). The old style, before they existed, was to create a list of 2-tuples (key/value pairs) in a list comprehension and pass that to dict().


A great typing system is generally a good thing if many people work on the same large project. I love how nim typings gets out of your way but are flexible enough to not tie you down.

That being said - by Rich Hickey - typing also add a lot of complexity and non-optimal bindings between stuff. Untyped incremental development with just simple scalar types, and a single list, map and set type is wonderful. Large refactorings, not so much.

Adding gradual typing to a project often gives you the worst of the two worlds. You still fear changing stuff, _and_ have lots of overhead doing all the typing. Either your project is fully type checked at compile time or it isn't.

Python match statements are useful for checking structure and de-duplicating the container name:

    result = {}        
    for temperature in temperatures:
        match temperature:
            case {"city": city, "temp": temp}:
                if temp >= max_temp:
                    result[city] = temp
Oh, and python typing has come a long way:

    from typing import List, TypedDict, Dict

    class Temperature(TypedDict):
        city: str
        temp: int

    def filter_temperatures(temperatures: List[Temperature], min_temp: int) -> Dict[str, int]:
        result = {}
        
        for temperature in temperatures:
            match temperature:
                case {"city": city, "temp": temp}:
                    if temp >= min_temp: # Most of the time >= is what people mean.
                        result[city] = temp
                case _:
                    raise ValueError(f"Wrong temperature format: {temperature}")

        return result

    my_temperatures: List[Temperature] = [
        {"city": "City1", "temp": 19},
        {"city": "City2", "temp": 22},
        {"city": "City3", "temp": 21},
    ]

    print(filter_temperatures(my_temperatures, 20))
    print(filter_temperatures([{"typecheck error": "and runtimeerror"}], 20))




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: