2016-06-30 5 views
1

私はその可能性何かにwhileループを変換することができる方法があります場合、私は思っていた0 -> numこのループをマップ(lambda x:..)に変換することはできますか?

# Example of how the below works, for clarity 
# 
# base => [0,1,1,2,1,2,2] 
# index => 7 
# 
# {7} -- 
#  bin(7)    : 111 
#  bin(7-1)   : 110 
#  111 & 110   : 110 (6) 
#  append(base[6]+1) : append(3) 
#  //end 7 
# 
# base => [0,1,1,2,1,2,2,3] 

def countBits(num): 
    index = 1 
    base = [0] 

    while(index <= num): 
     base.append(base[(index & (index - 1))]+1) 
     index += 1 

    return base 

から各番号のバイナリ表現に1秒数をカウントする方法を最適化しようとしていますループされているのではなく、その場で行われますか?私の最初のアイデアは

base.append(map(lambda index: base[(index & (index -1))]+1, num))

...何かなどを行うことでした。しかし、これは本当にまったく何もしていません... baseは変わりません。私はちょうど map(lambda x:...)構文が何を理解していないと仮定します。私はそれを数回使って、リスト上で簡単に呼び出しました。

+1

これは実際に動作しますか? – jsbueno

+0

ちょうど1つの例を説明するコメントで更新されました – MrDuk

+1

ループの本体があなたが追加しているものを参照する場合、ループをリスト内包または 'map'式にするのはかなり困難です。 'base.append(base [...])'は、簡単な時間を1つのライナーに変換しない赤いフラグです。 – Kevin

答えて

0

私は2つの(機能的なスタイルの)ソリューションを見つけましたが、「適切な」ものではありません。おそらく、どちらも遅くなり、ループするでしょう。

マップとの最初ではないが、とは削減:マップと

def countBits2(num): 
    from functools import reduce 
    index = 1; 
    base = reduce(lambda base, index: (base.append(base[(index & (index - 1))]+1), base)[1], range(1, num+1), [0]) 
    return base 

第二:

def countBits3(num): 
    base = [0]  
    def m_append(index): 
     val = base[(index & (index - 1))]+1 
     base.append(val) 
     return val 

    return [0] + list(map(m_append, range(1, num+1))) 
    #also possible to return base 
    #list(map(...)) # list required to force mapping on py3 
    #return base 

m_appendは、ラムダ(などでの試みを減らすのと同じ方法)に書き換えられるかもしれませんが、それは非常に長くなりますラムダ。

0

多分このようなものが欲しいですか?

num = 11 

base = [0] 
for _ in range(1, num): 
    base.extend(map(lambda index: base[(index & (index -1))] + 1, [_])) 

結果:

[0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2] 
関連する問題