__init__ with multiple list values

G

Gnarlodious

Initializing a list of objects with one value:

class Order:
def __init__(self, ratio):
self.ratio=ratio
def __call__(self):
return self.ratio

ratio=[1, 2, 3, 4, 5]
Orders=[Order(x) for x in ratio]


But now I want to __init__ with 3 values:

class Order:
def __init__(self, ratio, bias, locus):
self.ratio=ratio
self.bias=bias
self.locus=locus
def __call__(self):
return self.ratio, self.bias, self.locus

ratio=[1, 2, 3, 4, 5]
bias=[True, False, True, False, True]
locus=['A', 'B', 'C', 'D', 'E']
Orders=[Order(x,y,z) for x,y,z in [ratio, bias, locus]]

How to do it?

-- Gnarlie
 
C

Chris Angelico

Orders=[Order(x,y,z) for x,y,z in [ratio, bias, locus]]

Assuming that you intend to take the first element of each list, then
the second, and so on, you'll want to use zip():

Orders=[Order(x,y,z) for x,y,z in zip(ratio, bias, locus)]

With your syntax, Python iterates over a three-element list. The first
iteration, it looks at 'ratio' and tries to unpack that into x,y,z;
this doesn't work, because ratio has five elements. The second
iteration would try to unpack 'bias', and the third would go for
'locus'.

The zip function returns tuples of (ratio[N], bias[N], locus[N]) for
successive Ns:
[(1, True, 'A'), (2, False, 'B'), (3, True, 'C'), (4, False, 'D'), (5,
True, 'E')]

ChrisA
 
M

MRAB

Initializing a list of objects with one value:

class Order:
def __init__(self, ratio):
self.ratio=ratio
def __call__(self):
return self.ratio

ratio=[1, 2, 3, 4, 5]
Orders=[Order(x) for x in ratio]


But now I want to __init__ with 3 values:

class Order:
def __init__(self, ratio, bias, locus):
self.ratio=ratio
self.bias=bias
self.locus=locus
def __call__(self):
return self.ratio, self.bias, self.locus

ratio=[1, 2, 3, 4, 5]
bias=[True, False, True, False, True]
locus=['A', 'B', 'C', 'D', 'E']
Orders=[Order(x,y,z) for x,y,z in [ratio, bias, locus]]

How to do it?
Use 'zip':

Orders=[Order(x,y,z) for x,y,z in zip(ratio, bias, locus)]
 
J

Jean-Michel Pichavant

Gnarlodious said:
Initializing a list of objects with one value:

class Order:
def __init__(self, ratio):
self.ratio=ratio
def __call__(self):
return self.ratio

ratio=[1, 2, 3, 4, 5]
Orders=[Order(x) for x in ratio]


But now I want to __init__ with 3 values:

class Order:
def __init__(self, ratio, bias, locus):
self.ratio=ratio
self.bias=bias
self.locus=locus
def __call__(self):
return self.ratio, self.bias, self.locus

ratio=[1, 2, 3, 4, 5]
bias=[True, False, True, False, True]
locus=['A', 'B', 'C', 'D', 'E']
Orders=[Order(x,y,z) for x,y,z in [ratio, bias, locus]]


How to do it?

-- Gnarlie
I'm a little off topic but you may want to avoid having inconsistent
interfaces for your class methods, especially when it comes to special
methods like __init__ and __call__.

Having __call__ return a tuple with different length depending on the
initialization of the object is a bad idea. You will surely end up in
unpacking error in the future.

Same things for your attributes, the presence of bias is conditioned by
the object creation... Very bad idea :eek:)

o1 = Order([1,2,3])
o2 = Order([1,2,3], [4, 5, 6, [7, 8, 9])

print o1.bias
Unknown attribute

ratio, bias, locus = o2.call()

ratio, bias, locus = o1.call()
Unpacking error


You could do the following :

class Order:
def __init__(self, ratio, bias=None, locus=None):
self.ratio=ratio
self.bias=bias
self.locus=locus
def __call__(self):
return self.ratio, self.bias, self.locus


It would allow you to create your object with just the ratio and keep a
consistent interface. Unpacking the __call__ return will never fail, and
if you're interested in keeping only ratios, then you can write

ratio, _, _ = o1.call()

JM

PS : accessing attributes using the __call__ method sounds like a little
bit of magic for the lazy guy :eek:) People expect something to be executed
when calling an object, not getting its attributes. It would be better
to stick with the classic way : o1.ratio
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top