是否有任何非显式for
方法可以在对象上调用成员n
次?
我正在考虑一些map/reduce/lambda
方法,但我无法想出办法 - 如果有可能的话。
只是添加上下文,我正在使用BeautifulSoup
,我正在从html表中提取一些元素;我提取了一些元素,然后是最后一个元素。
因为我有:
# First value
print value.text
# Second value
value = value.nextSibling
print value.text
# Ninth value
for i in xrange(1, 7):
value = value.nextSibling
print value.text
我想知道是否有任何lambda
方法或其他方法可以让我这样做:
# Ninth value
((value = value.nextSibling) for i in xrange(1, 7))
print value.text
P.S。:不,使用for
方法没有任何问题,除了我真的很喜欢单行解决方案,这在我的代码中非常适合。
答案 0 :(得分:7)
我非常喜欢循环,但可以使用reduce
:
>>> class Foo(object):
... def __init__(self):
... self.count = 0
... def callme(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
答案 1 :(得分:4)
你想要一个单行代码:
for i in xrange(1, 7):
value = value.nextSibling
这是一行:
for i in xrange(1, 7): value = value.nextSibling
如果您正在寻找更实用的功能,那么您真正需要的是compose
功能,因此您可以撰写callme()
(或attrgetter('my_prop')
或其他)7次
答案 2 :(得分:2)
如果是BS
,您可以nextSiblingGenerator()
使用itertools.islice
来获取第n个兄弟。它还可以处理没有第n个元素的情况。
from itertools import islice
nth = 7
next(islice(elem.nextSiblingGenerator(), nth, None), None)
答案 3 :(得分:2)
免责声明:eval
是邪恶的。
value = eval('value' + ('.nextSibling' * 7))
答案 4 :(得分:1)
啊!但是{3}在Python3中不可用,至少不是内置的。
所以这是我的尝试,可移植到Python2 / 3并基于OP失败的尝试:
reduce
假设[globals().update(value=value.nextSibling) for i in range(7)]
是全局变量。如果value恰好是一个成员变量,那么写一下:
value
您无法使用[self.__dict__.update(value=value.nextSibling) for i in range(7)]
,因为列表推导会创建嵌套的本地范围,因此真正的locals()
无法直接使用。但是,您可以通过一些工作来捕获它:
locals()
如果你不介意重复行数,那就更容易了:
(lambda loc : [loc.update(x=x.nextSibling) for i in range(7)])(locals())
或者,如果你真的喜欢单行:
loc = locals()
[loc.update(value=value.nextSibling) for i in range(7)]
是的,Python也可以使用loc = locals() ; [loc.update(value=value.nextSibling) for i in range(7)]
8 - )
<强>更新强>:
另一个奇特的变体,现在使用;
而不是列表理解:
map
注意巧妙地使用列表乘法来捕获当前list(map(lambda d : d.update(value=value.nextSibling), 7 * [locals()]))
和同时创建初始迭代。
答案 5 :(得分:1)
最直接的写作方式是:
value = reduce(lambda x, _: x.nextSibling, xrange(1,7), value)