2009-06-19 5 views
1

私はリンク式のリストのような階層構造をトラバースする方法をリスト式を使って考えようとしてきましたが、うまくいくようなことは考えていません。リストの理解を使用してリンクされたリストをどのように歩くのですか?

基本的に、私はこのコードを変換したい:のようなワンライナーに

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

を:

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

私も、???一部でトラバーサルを行う方法がわからないんだけど、一般的な方法で(その可能性がある場合)。私は同様のタイプの属性を持ついくつかの構造体を持っており、それぞれに対して降伏関数を書いているとは思わない。

編集:その既にオブジェクト自体の中に含まれる値を反復するために使用されるため

Iは、オブジェクト自体の__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) 

答えて

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

私の個人的なヘルパーライブラリは年の同様の固定小数点のような機能を持っている...それは迅速なハックのためにかなり便利です。

+0

はい!これは私が探していたものです。私は私の適応で私の答えを更新しました。 –

+0

'fixedpoint'は[David Xの' cfor'](http://stackoverflow.com/questions/2740901/simulating-c-style-for-loops-in-python/2741943#2741943)のように書くことができます'def fixedpoint(f、start、stop):リターンcfor(開始、ラムダ現在:現在の!=停止、f)' –

1

リスト内包表記は、イテレータ(next()メソッドを持っている)であるオブジェクトで動作します。このように反復できるようにするには、構造体のイテレータを定義する必要があります。

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

あなたのLinkedListのは、それが正しく動作するために反復可能である必要があります。

Here's a good resource on it. (PDF warning)イテレータとジェネレータの両方で非常に深いです。

あなたがそれを行うたら、ちょうどこの行うことができます:あなたはあなたのソリューションが一般的になりたい場合は、一般的なtechiqueを使用

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

そのPDFはアクセスが制限されている可能性があります。 – SumNeuron

関連する問題