[Tutor] Playing with generators
Mats Wichmann
mats at wichmann.us
Wed Aug 10 13:12:52 EDT 2022
On 8/10/22 05:32, Leam Hall wrote:
> I'm wondering if there's a way to combine "make_person" with the
> generator in "for fname, peep in". Even if it can be done, should it be
> done? Or would the code be overly complex?
>
> The goal is to parse a group of data, and create a dict where the value
> is an object created from the data, and the key is an attribute of the
> object itself.
>
>
> class Person():
> def __init__(self, data = {}):
don't do this: don't use a mutable default argument
> self.fname = data.get('fname', 'fred')
> self.lname = data.get('lname', 'frank')
>
> data = [
> { 'fname':'Wilbur', 'lname':'Lefron' },
> { 'fname':'Al', 'lname':'Lefron' },
> { 'fname':'Jo', 'lname':'Franco' },
> { 'fname':'Mon', 'lname':'Pascal' },
> { 'fname':'Gray', 'lname':'Webb-Marston'},
> ]
>
> def make_person(data):
> ps = ( Person(d) for d in data)
> return ps
> peeps = {}
>
> for fname, peep in ( (p.fname, p) for p in make_person(data) ):
> peeps[fname] = peep
>
>
> for person in peeps.values():
> print(person.lname)
>
Sorry, Leam, it's a little hard to figure out what you're looking for
here. Yes, you can combine things - the key (IMHO) is to make
make_person return the right thing, so you don't get so convoluted
unpacking things. I'd make make_person the generator, too, and use a
dict comprehension. Here's a quick rewrite that I *think* does what I
think you are after. Using a dataclass gets you some stuff "for free"
and is useful here since as presented, it *is* only a data class. "Nice
printing" is one of the things you get for free. The other "trick" in
here is that since each entry in data is a dict, you can use dict
unpacking when creating the dataclass instance, so the args will match
the attributes you define.
from dataclasses import dataclass
@dataclass
class Person():
fname: str = "fred" # assuming you really want these as the
defaults....
lname: str = "frank"
data = [
{"fname": "Wilbur", "lname": "Lefron"},
{"fname": "Al", "lname": "Lefron"},
{"fname": "Jo", "lname": "Franco"},
{"fname": "Mon", "lname": "Pascal"},
{"fname": "Gray", "lname": "Webb-Marston"},
]
def make_person(data):
""" Creates Person instances, yielding a lookup key and the instance."""
for d in data:
p = Person(**d)
yield p.fname, p
peeps = {k: v for k, v in make_person(data)}
print(peeps)
More information about the Tutor
mailing list