Python 压缩";"-时间对象成员调用

Python 压缩";"-时间对象成员调用,python,for-loop,lambda,beautifulsoup,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

是否有任何非显式的
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

注:不,对于
for
方法没有任何问题,除了我非常喜欢单行程序解决方案,这将非常适合我的代码。

我非常喜欢循环,但是你可以使用
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
>>类Foo(对象):
...     定义初始化(自):
...        self.count=0
...     def callme(self):
...        self.count+=1
...        回归自我
... 
>>>a=Foo()
>>>减少(λx,y:x.callme(),范围(7),a)
>>>伯爵
7.

您想要一个与此等效的单行程序:

for i in xrange(1, 7):
    value = value.nextSibling
这是一行:

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

如果您正在寻找更具功能性的东西,那么您真正想要的是一个函数,因此您可以将
callme()
(或
attrgetter('my_prop')
,或其他内容)组合7次。

如果是
BS
,您可以使用
nextSiblingGenerator()
itertools.islice
来获得第n个兄弟。它还可以处理没有第n个元素的情况

from itertools import islice

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

啊!!但是,
reduce
在Python3中不可用,至少作为内置组件是不可用的

这是我的尝试,可移植到Python2/3,基于OP失败的尝试:

[globals().update(value=value.nextSibling) for i in range(7)]
它假定
是一个全局变量。如果值恰好是成员变量,则改为写入:

[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)]
或者如果你真的喜欢一句台词:

loc = locals() ; [loc.update(value=value.nextSibling) for i in range(7)]
是的,Python可以使用
太多(8-)

更新

另一个奇特的变体,现在是
map
,而不是列表:

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

请注意,巧妙地使用列表乘法捕获当前的
局部变量()
,同时创建初始iterable。

免责声明:
eval
是邪恶的

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

最直接的书写方式是:

value = reduce(lambda x, _: x.nextSibling, xrange(1,7), value)

在没有下一个兄弟的情况下,<代码> NeXsiBLIG/<代码>返回什么?@ SR2222,您可以考虑<代码> NExsisibIs/COD>总是返回一个有效值;我想指出的是关于代码编写的问题——工作仅仅是一个结果(:所以这不是一个“句柄n长度列表”问题,而是一个“特定切片的一行程序”问题)问题。@sr2222我希望标题编辑更适合问题本身。谢谢你指出它。@StoryTeller--我很高兴看到满足OP标准的替代方案。正如我前面所说的,我不会使用这个。我会使用循环。@StoryTeller:OP明确地说他想要一行,尽管他知道它不是惯用的。所以这是一个完美的合理的答案。使用map不是更容易吗?如
map(lambda:a.callme(),range(7))
啊,当然……我忽略了一个事实,返回的对象被用于连续调用,因为在这个例子中它没有什么区别。@StoryTeller:准备了什么?他刚刚创建了一个简单的例子来测试他的一行。天哪,伙计!我不知道我能做到这一点(:让我也试试这个!顺便说一句——你作弊了;-)@mgilson:code golf没有作弊。(我对你的评论投了更高的票,所以你会得到更高的分数,这算是在高尔夫比赛中输了,对吧?)哇,老兄!我也要试试这个。现在我很担心我不知道该选择哪个答案。^^你可以把
try:from functools import reduce;除了:pass
放在顶部,然后代码可以与Python 2和3一起移植。我很确定这是
locals
滥用——特别是因为修改locals会导致这种滥用修改当前名称空间(在这种情况下,你只会得到一个
None
,并且没有变异的
值的列表)是的,这是非常邪恶的(:也很好;我猜这是从公认的答案中对vars的某种程度上的缩短。只是一个问题:
不会减少(lambda x,\ux.nextSibling,xrange(1,7),value)
就足够了,因为赋值已经在reduce过程中执行了?@Rubens:赋值是什么意思?怎么可能呢?Python是按值传递的。函数不能赋值给调用方的变量。