Skip to content Skip to sidebar Skip to footer

Compressing "n"-time Object Member Call

Is there any non-explicit for way to call a member n times upon an object? I was thinking about some map/reduce/lambda approach, but I couldn't figure out a way to do this -- if it

Solution 1:

I have a strong preference for the loop, but you could use reduce:

>>>classFoo(object):...def__init__(self):...       self.count = 0...defcallme(self):...       self.count += 1...return self...>>>a = Foo()>>>reduce(lambda x,y:x.callme(),range(7),a)
<__main__.Foo object at 0xec390>
>>>a.count
7

Solution 2:

You want a one-liner equivalent of this:

for i in xrange(1, 7):
    value = value.nextSibling

This is one line:

for i in xrange(1, 7): value = value.nextSibling

If you're looking for something more functional, what you really want is a compose function, so you can compose callme() (or attrgetter('my_prop'), or whatever) 7 times.

Solution 3:

In case of BS you can use nextSiblingGenerator() with itertools.islice to get the nth sibling. It would also handle situations where there is no nth element.

from itertools import islice

nth = 7next(islice(elem.nextSiblingGenerator(), nth, None), None)

Solution 4:

Disclaimer: eval is evil.

value = eval('value' + ('.nextSibling' * 7))

Solution 5:

Ah! But reduce is not available in Python3, at least not as a built in.

So here is my try, portable to Python2/3 and based on the OP failed attempt:

[globals().update(value=value.nextSibling) for i inrange(7)]

That assumes that value is a global variable. If value happens to be a member variable, then write instead:

[self.__dict__.update(value=value.nextSibling) for i inrange(7)]

You cannot use locals() because the list comprehension creates a nested local scope, so the real locals() is not directly available. However, you can capture it with a bit of work:

(lambda loc : [loc.update(x=x.nextSibling) for i in range(7)])(locals())

Or easier if you don't mind duplicating the number of lines:

loc = locals()
[loc.update(value=value.nextSibling) for i in range(7)]

Or if you really fancy one-liners:

loc = locals() ; [loc.update(value=value.nextSibling) for i in range(7)]

Yes, Python can use ; too 8-)

UPDATE:

Another fancy variation, now with map instead of the list comprehension:

list(map(lambda d : d.update(value=value.nextSibling), 7 * [locals()]))

Note the clever use of list multiplication to capture the current locals()and create the initial iterable at the same time.

Post a Comment for "Compressing "n"-time Object Member Call"