News for hackers. Stuff that matters.
Re:Advanced Python Mastery – A Course by David Beazley by thrdbndndn on Wednesday July 19, 2023 @11:07AM (#36787704)
There is always list comprehension.

So `portfolio = [{'name': row[0], 'shares': int(row[1]), 'price': float(row[2]) for row in rows]`

But if it's more complicated than this (like if there is conditional(s) inside the loop), I'd recommend just stick with the current approach. It's possible to have even multiple conditionals in list comprehension, but it's not really very readable. If you do want to, walrus operator can make things better

(something like `numbers = [m[1] for s in array if (m := re.search(r'^.*(\d+).*$', s))]`)

Re:Advanced Python Mastery – A Course by David Beazley by nurbl on Wednesday July 19, 2023 @11:23AM (#36787951)
They can be more readable than that at least, e.g.:

    keys = "name", "shares", "price"
    portfolio = [
        dict(zip(keys, row))
        for row in rows
    ]
If I had to do more complex stuff than building a dict like this I'd move it into a function. That tends to make the purpose more clear anyway.

That said, it's fine to append to a list too, I just prefer comprehensions when they fit the job. In particular, if you're just going to iterate once over this list anyway, you can turn it into a iterator comprehension by replacing [] by () and save some memory.

Re:Advanced Python Mastery – A Course by David Beazley by roywiggins on Wednesday July 19, 2023 @11:11AM (#36787764)
You can alternately stick the logic into a function, which maintains the readability.

    def get_record(row):
        return {
                'name': row[0],
                'shares': int(row[1]),
                'price': float(row[2])
        }
    return [ get_record(r) for r in rows ]
or

    return list(map(get_record, rows))
Re:Advanced Python Mastery – A Course by David Beazley by thrdbndndn on Wednesday July 19, 2023 @11:16AM (#36787856)
I do like to use ad hoc functions to make things cleaner (mainly for the handy "early" return behavior), but in this case I don't find it's much better than "just create an empty list first and do a for loop".
Re:Advanced Python Mastery – A Course by David Beazley by gen220 on Wednesday July 19, 2023 @11:30AM (#36788058)
Personally, I enjoy the pattern of making the return type a dataclass and make this function a static method on the dataclass, something like `def from_data(self, data: Dict) -> PortfolioRow`.

In 2023, it's rude to return dictionaries. :)

Re:Advanced Python Mastery – A Course by David Beazley by proamdev123 on Wednesday July 19, 2023 @12:17PM (#36788853)
> In 2023, it's rude to return dictionaries. :)

Why do you say that?

I think you were partially kidding, but also half serious. What’s the issue with returning dictionaries, and why should we be returning dataclasses instead?

Asking for my own learning.

Re:Advanced Python Mastery – A Course by David Beazley by sanderjd on Wednesday July 19, 2023 @12:35PM (#36789189)
Data classes are "self-documenting" with respect to the "keys" you can expect to be present. Relatedly, they enable meaningful type hints:

  def some_method(input: Dict[str, int]):
    ...
You can just as easily call `some_method({"foo": 1})` as `some_method({"bar": 2})`.

vs.

  def some_method(input: MyDataClassWithFoo):
    ...
Now you can't pass a dict where the key is "bar" and presumably get a KeyError when it tries to look up a "foo" key, you can only pass a MyDataClassWithFoo.
Re:Advanced Python Mastery – A Course by David Beazley by gen220 on Wednesday July 19, 2023 @02:08PM (#36790684)
Regarding the 2023 part, it's because dataclasses in Python are pretty fully-featured and part of the stdlib, so building rich data structures is quick, ergonomic, and helps remove/centralize boilerplate and parsing (aka validating, see https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-va...).

Regarding rude, yea it was a bit tongue-in-cheek (I would never hold a grudge against somebody for returning a dict).

You should generally define an interface for your function that's as precise as its logic allows for. `Dict` is as good as `Any`: it doesn't tell you very much about what the function internally expects. The sibling comment to mine does a good job going through this.