压缩“n”时间对象成员调用

时间:2013-01-31 21:58:17

标签: python for-loop lambda beautifulsoup

是否有任何非显式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方法没有任何问题,除了我真的很喜欢单行解决方案,这在我的代码中非常适合。

6 个答案:

答案 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)