2015-08-08 33 views
3

我正在玩推動Python(2.7,通過pythonista iOS解釋器)做一些奇怪的功能的東西。具體來說,我試圖使用嵌套的if-else lambdas和map來實現一行fizzbuzz。但我對這種骯髒的詭計很陌生,並且它不太好。Python中返回函數對象而不是值的嵌套if-else lambdas(傳遞變量通過?)

看看下面的代碼:

alist = [1, 2, 3, 15, 5] 
claw = map(lambda x: 'Fizzbuzz' if x % 15 == 0 else lambda x: 'Fizz' if x % 3 == 0 else lambda x: 'Buzz' if x % 5 == 0 else x, alist) 
print "claw" 
print claw 
print 
claw2 = map(lambda x: 'scratch' if x == 1 else 2, alist) 
print "claw2" 
print claw2 

此代碼產生以下輸出:

claw 
[<function <lambda> at 0x3f19fb4>, <function <lambda> at 0x36ba534>, <function <lambda> at 0x3ffa3e4>, 'Fizzbuzz', <function <lambda> at 0x3ffaa74>] 

claw2 
['scratch', 2, 2, 2, 2] 

周圍搜索後,它很可能是在爪的問題是,列表元素不傳遞給內部lambda(根據這個SO:Scope of python lambda functions and their parameters)。好了,然後我試着築巢地圖太:

claw3 = map(lambda x: 'Fizzbuzz' if x % 15 == 0 else map(lambda x: 'Fizz' if x % 3 == 0 else map(lambda x: 'Buzz' if x % 5 == 0 else x, alist), alist), alist) 
print "claw3" 
print claw3 

至少產生的值,但顯然不完全是我是想實現:

claw3 
[[[1, 2, 3, 'Buzz', 'Buzz'], [1, 2, 3, 'Buzz', 'Buzz'], 'Fizz', 'Fizz', [1, 2, 3, 'Buzz', 'Buzz']], [[1, 2, 3, 'Buzz', 'Buzz'], [1, 2, 3, 'Buzz', 'Buzz'], 'Fizz', 'Fizz', [1, 2, 3, 'Buzz', 'Buzz']], [[1, 2, 3, 'Buzz', 'Buzz'], [1, 2, 3, 'Buzz', 'Buzz'], 'Fizz', 'Fizz', [1, 2, 3, 'Buzz', 'Buzz']], 'Fizzbuzz', [[1, 2, 3, 'Buzz', 'Buzz'], [1, 2, 3, 'Buzz', 'Buzz'], 'Fizz', 'Fizz', [1, 2, 3, 'Buzz', 'Buzz']]] 

現在我的大腦已經用完了。顯然,重複調用映射是反覆評估整個列表,但如果沒有辦法將變量獲取到嵌套lambdas沒有它,我卡住了嗎?我想可能有一些解決方案涉及變更列表,比如每次lambda返回值時刪除列表項,但這看起來不合理複雜以及完全無效。我非常接近單線功能fizzbuzz!有人在這裏有任何線索嗎?

編輯:謝謝,你們都。爲了您的娛樂集體/回報的,有些完全實現一個在線fizzbuzzes:

https://gist.github.com/paultopia/d360116128c787e22ce8

回答

2

的問題是,你是不是調用內部lambda表達式。如果條件爲假,則類似a if b else lambda: ...的表達式僅返回lambda本身(即,函數對象)。您可以使用此得到您的結果:

>>> claw = map(lambda x: 'Fizzbuzz' if x % 15 == 0 else (lambda x: 'Fizz' if x % 3 == 0 else (lambda x: 'Buzz' if x % 5 == 0 else x)(x))(x), alist) 
>>> claw 
[1, 2, 'Fizz', 'Fizzbuzz', 'Buzz'] 

但是,你甚至都不需要做的一切,只是爲了獲得一個行fizzbuzz。你可以直接嵌套在彼此內的if/else表情單一的λ:

>>> claw = map(lambda x: 'Fizzbuzz' if x % 15 == 0 else 'Fizz' if x % 3 == 0 else 'Buzz' if x % 5 == 0 else x, alist) 
>>> claw 
[1, 2, 'Fizz', 'Fizzbuzz', 'Buzz'] 

而且你不需要任何lambda表達式都,你可以只是一個列表理解:

>>> claw = ['Fizzbuzz' if x % 15 == 0 else 'Fizz' if x % 3 == 0 else 'Buzz' if x % 5 == 0 else x for x in alist] 
>>> claw 
[1, 2, 'Fizz', 'Fizzbuzz', 'Buzz'] 
1

我相信你想要的是:

claw = map(lambda x: 'fizzbuz' if x%15==0 else 'fizz' if x%3==0 else 'buzz' if x%5==0 else x, alist) 
1

你的問題是運營商優先。你可以看到這個更清楚,如果你更換所有的lambda表達式先用字符串後,並添加括號來澄清:

>>> alist = [1, 2, 3, 15, 5] 
>>> claw = map(lambda x: ('Fizzbuzz' if (x % 15 == 0) else "LAMBDA_FIZZ" if (x % 3 == 0) else "LAMBDA_BUZZ" if (x % 5 == 0) else x), alist) 
>>> claw 
[1, 2, 'LAMBDA_FIZZ', 'Fizzbuzz', 'LAMBDA_BUZZ'] 

BrenBarn已經發布了一個答案,顯示方式與多個lambda表達式要做到這一點,但更好辦法做到這一點,同時仍然使用地圖和拉姆達就是這樣的:

claw = map(lambda x: 'FizzBuzz' if (x % 15 == 0) else 'Fizz' if (x % 3 == 0) else 'Buzz' if (x % 5 == 0) else x, alist) 

雖然我寧願使用,即使你堅持使用一個班輪列表理解:

claw = ['FizzBuzz' if (x % 15 == 0) else 'Fizz' if (x % 3 == 0) else 'Buzz' if (x % 5 == 0) else x for x in alist] 

這是我會怎麼真正做到這一點:

def fizzbuzz(x): 
    if x % 15 == 0: 
     return 'FizzBuzz' 
    elif x % 3 == 0: 
     return 'Fizz' 
    elif x % 5 == 0: 
     return 'Buzz' 
    else: 
     return x 

claw = [fizzbuzz(x) for x in alist] 
2

如果我能提出一個稍微不同的方法,我會考慮更Python。列表解析也表達了函數操作,但在python中不太詳細。請嘗試以下操作:

claw = ['Fizzbuzz' if x % 15 == 0 
     else 'Fizz' if x % 3 == 0 
     else 'Buzz' if x % 5 == 0 
     else x for x in alist] 

它使我的觀點更清晰。