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

LinkedList が適切に機能するには、反復可能である必要があります。

ここに良いリソースがあります。(PDF 警告)イテレータとジェネレータの両方について非常に詳しく説明されています。

これを行うと、次のことができるようになります。

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