2012-02-25 3 views
3

このコードを書く良い方法はありますか?私はそれがとても簡単だと知っていますが、私が書いた方法はとても反復的です。Python:joinを使ってif-thenブロックを書くより良い方法は?

私は一行の天才コードを探している必要はありません。

ありがとうございます!

def __unicode__(self): 
    location = [] 

    if self.room != None: 
     location.append(self.room) 
    if self.floor != None: 
     location.append(self.floor) 
    if self.building != None: 
     location.append(self.building) 

    location.append(self.property) 

    return ", ".join(location) 

self.propertyは常にself.roomself.floor、そしてself.buildingのための真のされていない、設定されています。ちなみに、これはDjangoコードのmodels.pyの一部です。

サイドの質問:悪い考え変数名としてpropertyを使用していますか?私はpropertyが構文の下で強調表示されていることに気づいたが、私はそれを見て、それはPython reserved wordではない。ここで

は完全なクラスです:それは自動的にTrueに評価された最初の式の値を返します

first = self.room or self.floor or self.building 
if first: 
    location.append(first) 

class Location(models.Model): 
    def __unicode__(self): 
     location = [] 

     if self.room != None: 
      location.append(self.room) 
     if self.floor != None: 
      location.append(self.floor) 
     if self.building != None: 
      location.append(self.building) 

     location.append(self.property) 

     return ", ".join(location) 

    comments = models.TextField(blank = True) 
    room  = models.CharField(max_length = 135, blank = True) 
    floor  = models.CharField(max_length = 135, blank = True) 
    building = models.CharField(max_length = 135, blank = True) 
    property = models.ForeignKey(Property) 
    t_created = models.DateTimeField(auto_now_add = True) 
    t_modified = models.DateTimeField(auto_now = True) 

答えて

9

この最初の部分は、追加する最初のnon-None要素を選択した場合の元の質問に対する回答でした。

狂った1行やあまりにも派手なことをしようとすることなく、私はこれはかなり簡単な解決策だと思う。ループして、最初のものを追加してください。あなたはワンライナーを使用する場合は

for loc in (self.room, self.floor, self.building): 
    if loc is not None: 
     location.append(loc) 
     break 

は、ここにリスト内包である:

location = [l for l in (self.room, self.floor, self.building) if l is not None][:1] 

その最後の1に読みやすく妥協は次のようになります。

options = (self.room, self.floor, self.building) 
location = [l for l in options if l is not None][:1] 

@tzamanは正しかったですあなたの変数名にpropertyを使わないようにしてください。これは、組み込み型である:

:ので、あなたのコメントの中で、あなたが実際に何を望むか言及

>>> property 
<type 'property'> 

class property(object) 
| property(fget=None, fset=None, fdel=None, doc=None) -> property attribute 
| 
| fget is a function to be used for getting an attribute value, and likewise 
| fset is a function for setting, and fdel a function for del'ing, an 
| attribute. Typical use is to define a managed attribute x: 

更新

はどれも、その超シンプルなリストカンプないではない、これらのプロパティのいずれかでした

locations = [l for l in (self.room, self.floor, self.building) if l is not None] 

アップデート2:@Vaughnカトーのコメントで素晴らしい提案

locations = filter(None, [self.room, self.floor, self.building]) 
+1

またはlocation = filter(なし、オプション)[:1] –

+0

もし彼が実際に最初のものだけを望んでいたら、それはうまくいくでしょう。また、彼は後でそれをリストにキャストする必要があります。 – jdi

+0

もちろん、[:1]を取り除くことでそれらのすべてを得ることができます。タプルではなくリストを渡すと、リストが返されます。 –

5

ちょうどor演算子を使用します。 また、propertyは予約語ではありませんが、built-inです。これを使用しないでください。

+0

これに若干の問題が、すべての場合これらのプロパティのいずれかがNoneである場合、彼はNoneを追加します。 – jdi

+0

@jdi - 良い点、それを世話するために編集しました。 – tzaman

+0

賢い!しかし、私は "elif"をしたくないことに気付きました。私は3つのifを持っていたはずです。おっと、3つの 'if'のために' or'は動作しません。しかし、私はまだ何かを学んだ。ありがとう! – hobbes3

3

ビルは何JDI上に掲載:

self.propertyはなし、とヴォーンカトーのポスト上の建物になることはありませんという事実を利用して
def __unicode__(self): 
    location = filter(None,[self.room,self.floor,self.building]) 
    location.append(self.property) 
    return ", ".join(location) 
1

def __unicode__(self): 
    location = filter(None,[self.room,self.floor,self.building, self.property]) 
    return ", ".join(location) 
関連する問題