2013-05-07 124 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