如何使用列表理解走上链表?

时间:2009-06-19 21:12:30

标签: python list-comprehension

我一直试图想办法使用列表表达式遍历层次结构,比如链表,但是没有提出任何似乎有用的东西。

基本上,我想转换此代码:

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 个答案:

答案 0 :(得分: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)

答案 1 :(得分:2)

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

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

只要这些值都不等于停止,它将返回一个生成器开始,f(开始),f(f(开始)),f(f(f(开始))),...

用法:

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

我的私人帮助程序库多年来具有类似固定点的功能......对于快速黑客攻击非常有用。

答案 2 :(得分:1)

List comprehension适用于作为迭代器的对象(具有next()方法)。您需要为结构定义一个迭代器,以便能够以这种方式迭代它。

答案 3 :(得分:1)

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

Here's a good resource on it. (PDF warning)迭代器和生成器都非常深入。

一旦你这样做,你就能做到这一点:

print ".".join( [o.name for o in self] )