2013-05-07 32 views
9

通常我知道我們可以做sum([func(x,x) for x in i]),但我得到了一個if檢查和兩個for循環,那麼編寫代碼的最蟒蛇方式是什麼?你可以認爲相似性會返回一個數字,不管你給它什麼類型。你也可以假設它只會得到整數和字符。Python,最好的方法來寫兩個循環的總和

x = 0 
if isinstance(a, dict) or isinstance(a, list) or isinstance(a, tuple): 
    for i in a: 
     for j in b: 
      x += similarity (i,j) 
+5

'if'不在任何循環內,所以...爲什麼它需要在'sum'內? – abarnert 2013-05-07 20:12:30

+1

對於你的例子,你可以用'sum(func(x,y)for x in i)'作爲生成器,而不是'sum([func(x,y)for x in i]不生成中間列表 – 2013-05-07 22:08:18

回答

10

也許是這樣的:

x=0 
if isinstance(a,(dict,list,tuple)): 
    x=sum(similarity(i,j) for i in a for j in b) 

或者:

x=(sum(similarity(i,j) for i in a for j in b) if isinstance(a,(dict,list,tuple)) 
    else 0) 

或(假設一個字符串,設置或其他可迭代類型由於某種原因不會破壞您的功能):

try: 
    x=sum(similarity(i,j) for i in a for j in b) 
except TypeError: 
    x=0 

如果您特別測試,如果事情是可迭代的,你能做到這一點是這樣的:

from collections import Iterable 
if isinstance(e, Iterable): 
    ... 

如果你不希望某些迭代類型,應對那些:

if isinstance(e, Iterable) and not isinstance(el, str): 
    # an iterable that is not a string... 
+5

沒有當您只需將所有類型傳遞給'isinstance'本身時,就可以在'isinstance'中使用'any'。 – abarnert 2013-05-07 20:17:29

+0

好的 - 謝謝。接得好。編輯製作 – dawg 2013-05-07 20:19:17

+1

Downvoter - 請問爲什麼?我做了建議編輯.. – dawg 2013-05-07 20:42:32

5

由於if不是一個循環裏面,當你轉換它,它並不需要在名單解析裏:

x = 0 
if isinstance(a, dict) or isinstance(a, list) or isinstance(a, tuple): 
    x = sum([similarity(i, j) for i in a for j in b]) 

同時,你真的不需要一個列表這裏的理解,一臺發電機的表達式將具有同樣的效果,而無需建立一個列表:

x = 0 
if isinstance(a, dict) or isinstance(a, list) or isinstance(a, tuple): 
    x = sum(similarity(i, j) for i in a for j in b) 

同時,isinstance可以採取一個類型的tuple來檢查,所以:

x = 0 
if isinstance(a, (dict, list, tuple)): 
    x = sum(similarity(i, j) for i in a for j in b) 

...但說真的,我不認爲你要在第一時間進行檢查。只要a是任何可迭代的,代碼將工作,所以...爲什麼我應該強制它是那些特定類型?如果你不希望有一個例外,只是處理異常:

try: 
    x = sum(similarity(i, j) for i in a for j in b)) 
except TypeError: 
    x = 0 
+0

@DSM:是的,我的答案已經說過了。但是,真的,他不應該使用它,就像我在編輯中解釋的那樣。 (無論如何,這與他提出的主要問題無關。) – abarnert 2013-05-07 20:18:04

+0

第一個版本有句子「同時,'isinstance'可以採用類型的'元組'來檢查,但是真的,爲什麼你需要檢查嗎?「我在第一次編輯中擴展了第一部分,在第二次編輯中擴展了第二部分。 – abarnert 2013-05-07 20:20:31

+0

+1 [EAFP](http://docs.python.org/2/glossary.html#term-eafp)成語。 – Johnsyweb 2013-05-07 20:21:39

0
if type(a) in [dict, list, tuple]: 
    x += sum(similarity(i, j) for i in a for j in b) 

呀,類型是不一樣的isistance但它不是一個戲劇性的問題..

如果OP想要使用類似於字典,列表或元組的所有代碼(所以對於子類和所有),它應該確實檢查a是否可迭代。

類似:

def isiterable(obj): 
    try: 
     iter(obj) 
     return True 
    except TypeError: 
     return False 

if isiterable(a): 
    x += sum(similarity(i, j) for i in a for j in b) 
+7

是不是'isinstance',並不是一個好主意 – cmd 2013-05-07 20:15:51

+1

好的愚蠢的問題,爲什麼不呢? – EasilyBaffled 2013-05-07 20:19:21

+0

@EasilyBaffled:如果我傳入的是某個「dict」子類的實例,該怎麼辦?這將與'isinstance'一起工作,但它不會在明確檢查'type'的情況下工作。 – abarnert 2013-05-07 20:21:31

9

你可能想是這樣的:

if isinstance(a, (dict, list, tuple)): 
    x = sum(similarity(i, j) for i in a for j in b) 
else: 
    x = 0 
+1

這是爲什麼降低了?誠然,它不會添加至少2個已有的答案中的任何內容,但是自那時候起就是downvote的原因? – abarnert 2013-05-07 20:27:04

+0

不知道downvote,而是爲了「辯護」答案:當它被寫入時,沒有其他答案將元組傳遞給'isinstance',也沒有顯示'sum'默認爲0,這使得無條件分配成爲不必要的。此外,一些現有的答案是不必要的羅嗦。 – user4815162342 2013-05-08 06:27:20

+0

考慮到解釋變化的選擇,OP不太可能理解,與給他一些顯然按照魔法做他想要的代碼的方式不同,因此他可以用自己的方式來編碼,而他不能維護甚至調試,我認爲前者「太羅嗦」。 (另外,我的答案是第一個,而且它沒有顯示使用'isinstance'和一個元組,它具有相同的信息:「同時,'isinstance'可以使用類型的'元組'來檢查... 「我沒有表現出來,因爲我認爲最好證明他根本不需要檢查類型。) – abarnert 2013-05-08 18:05:58

1

在一個線; )

x = sum(similarity(i, j) for i in a for j in b) if isinstance(a, (dict, list, tuple)) else 0 
+5

「[Readability counts](http://www.python.org/dev/peps/pep-0020/)」 – Johnsyweb 2013-05-07 20:19:59

+1

當然......這就是爲什麼我把笑臉放在那裏; ) – tamasgal 2013-05-07 20:22:45

+1

OP沒有要求編碼高爾夫。 – abarnert 2013-05-07 20:23:19

7

你可以使用一些功能從itertools,也許是:

from itertools import starmap, product 
x = sum(starmap(similarity, product(a, b))) 

和其他人所指出的,不妨通過一個類型的元組isinstance()如果你真的需要檢查。

+0

itertools-foo +1 – user4815162342 2013-05-08 20:41:30