9

通常我知道我们可以做到sum([func(x,x) for x in i]),但我有一个 if 检查和两个 for 循环,那么编写下面的代码的最 Pythonic 方式是什么。您可以假设无论您给出什么类型,相似性都会返回一个数字。你也可以假设它真的只会得到整数和字符。

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)
4

6 回答 6

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...
于 2013-05-07T20:13:59.393 回答
9

你可能想要这样的东西:

if isinstance(a, (dict, list, tuple)):
    x = sum(similarity(i, j) for i in a for j in b)
else:
    x = 0
于 2013-05-07T20:16:05.577 回答
7

您可以使用 中的一些函数itertools,也许:

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

正如其他人指出的那样,isinstance()如果您真的需要检查,也可以将类型的元组传递给。

于 2013-05-07T20:22:29.773 回答
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
于 2013-05-07T20:13:49.160 回答
1

在一行中;)

x = sum(similarity(i, j) for i in a for j in b) if isinstance(a, (dict, list, tuple)) else 0
于 2013-05-07T20:17:30.093 回答
0
if type(a) in [dict, list, tuple]:
    x += sum(similarity(i, j) for i in a for j in b)

是的,类型与 isistance 不同,但它不是一个戏剧性的问题..

如果 OP 想要将那段代码与任何类似 dict、list 或 tuples 的东西一起使用(因此使用子类和所有),它实际上应该只检查 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)
于 2013-05-07T20:14:28.590 回答