1

我一直在想一种方法来遍历层次结构,如链表,使用列表表达式,但没有想出任何似乎可行的方法。

基本上,我想转换这段代码:

p = self.parent
names = []
while p:
  names.append(p.name)
  p = p.parent
print ".".join(names)

变成像这样的单线:

print ".".join( [o.name for o in <???>] )

不过,我不确定如何以通用方式(如果可能的话)在???零件中进行遍历。我有几个具有相似类型属性的结构,并且不想为每个结构编写一个屈服函数。.parent

编辑:

我不能使用__iter__对象本身的方法,因为它已经用于迭代对象本身包含的值。大多数其他答案,除了 liori 的,硬编码属性名称,这是我想要避免的。

这是我根据 liori 的回答做出的改编:

import operator
def walk(attr, start):
  if callable(attr):
    getter = attr
  else:
    getter = operator.attrgetter(attr)

  o = getter(start)
  while o:
    yield o
    o = getter(o)
4

4 回答 4

6

我能想到的最接近的事情是创建一个父生成器:

# Generate a node's parents, heading towards ancestors
def gen_parents(node):
   node = node.parent
   while node:
      yield node
      node = node.parent

# Now you can do this
parents = [x.name for x in gen_parents(node)]
print '.'.join(parents)
于 2009-06-19T21:18:08.483 回答
2

如果您希望您的解决方案具有通用性,请使用通用技术。这是一个类似生成器的定点:

def fixedpoint(f, start, stop):
    while start != stop:
        yield start
        start = f(start)

只要这些值都不等于 stop,它将返回一个生成器产生 start, f(start), f(f(start)), f(f(f(start))), ...。

用法:

print ".".join(x.name for x in fixedpoint(lambda p:p.parent, self, None))

我的个人助手库多年来一直具有类似的定点功能……它对于快速破解非常有用。

于 2009-06-19T23:38:10.510 回答
1

列表推导适用于作为迭代器的对象(具有 next() 方法)。您需要为您的结构定义一个迭代器,以便能够以这种方式对其进行迭代。

于 2009-06-19T21:17:15.957 回答
1

您的 LinkedList 需要可迭代才能正常工作。

这是一个很好的资源。(PDF 警告)它对迭代器和生成器都非常深入。

一旦你这样做了,你就可以这样做:

print ".".join( [o.name for o in self] )
于 2009-06-19T22:57:35.677 回答