如何以pythonic方式将元组一分为二
How to divide a tuple into two in pythonic way
我遇到了一个问题:接收一个包含任何类型对象的元组,并将其分成两个元组:第一个,仅包含字符串;第二个,仅包含字符串;第二个,只有数字。
好的。标准算法类似于:
def separate(input_tuple):
return_tuple = ([],[])
for value in input_tuple:
if isinstance(value, str):
return_tuple[0].append(value)
if isinstance(value, numbers.Number):
return_tuple[1].append(value)
return tuple([tuple(l) for l in return_tuple])
这样,我们只迭代一次。
我的问题是:有没有办法以更 pythonic 的方式做到这一点?一条线?
我试过了
( tuple([i for i in input_tuple if isinstance(i,str)]), tuple([i for i in input_tuple if isinstance(i,numbers.Number)]))
但效率较低,因为我们对输入元组进行了两次迭代。
此外,
tuple([ tuple( [i for i in input_tuple if isinstance(i, k)]) for k in ((float ,int,complex), str) ])
有同样的问题,因为我们做了两次迭代。
是否有可能只迭代一次并仍然得到结果,或者因为我正在处理分离成两个元组,这是不可能的?
谢谢!
我想你可以这样做
my_tuple = ([],[])
for x in a_list:
my_tuple[isinstance(x,basestring)].append(x)
这会让它更 pythonic 我想......而且仍然很可读。
当然你也可以把它放在一个列表理解中,但不是很好:
[my_tuple[isinstance(x,basestring)].append(x) for x in a_list]
列表理解被抛弃了,它基本上被滥用到 for 循环中。
试试这个:
tuple(list(filter(lambda e: isinstance(e, t), input_tuple)) for t in (str,int))
它不是单行的,它甚至不等同于您最初所做的,但您可以使用列表容器来提供 "mapping" 功能:
>>> from numbers import Number
>>> tup = (1, '2', 3, '4', 5)
>>> di = {}
>>> for x in tup:
... di.setdefault(Number if isinstance(x, Number) else str if isinstance(x, str) else object, []).append(x)
...
>>> di[str], di[Number]
(['2', '4'], [1, 3, 5])
正如@PadraicCunningham 在评论中指出的那样,对于 Python 2,您可以使用 basestring
而不是 str
来捕获 Unicode 类型。
我遇到了一个问题:接收一个包含任何类型对象的元组,并将其分成两个元组:第一个,仅包含字符串;第二个,仅包含字符串;第二个,只有数字。
好的。标准算法类似于:
def separate(input_tuple):
return_tuple = ([],[])
for value in input_tuple:
if isinstance(value, str):
return_tuple[0].append(value)
if isinstance(value, numbers.Number):
return_tuple[1].append(value)
return tuple([tuple(l) for l in return_tuple])
这样,我们只迭代一次。
我的问题是:有没有办法以更 pythonic 的方式做到这一点?一条线?
我试过了
( tuple([i for i in input_tuple if isinstance(i,str)]), tuple([i for i in input_tuple if isinstance(i,numbers.Number)]))
但效率较低,因为我们对输入元组进行了两次迭代。
此外,
tuple([ tuple( [i for i in input_tuple if isinstance(i, k)]) for k in ((float ,int,complex), str) ])
有同样的问题,因为我们做了两次迭代。 是否有可能只迭代一次并仍然得到结果,或者因为我正在处理分离成两个元组,这是不可能的?
谢谢!
我想你可以这样做
my_tuple = ([],[])
for x in a_list:
my_tuple[isinstance(x,basestring)].append(x)
这会让它更 pythonic 我想......而且仍然很可读。
当然你也可以把它放在一个列表理解中,但不是很好:
[my_tuple[isinstance(x,basestring)].append(x) for x in a_list]
列表理解被抛弃了,它基本上被滥用到 for 循环中。
试试这个:
tuple(list(filter(lambda e: isinstance(e, t), input_tuple)) for t in (str,int))
它不是单行的,它甚至不等同于您最初所做的,但您可以使用列表容器来提供 "mapping" 功能:
>>> from numbers import Number
>>> tup = (1, '2', 3, '4', 5)
>>> di = {}
>>> for x in tup:
... di.setdefault(Number if isinstance(x, Number) else str if isinstance(x, str) else object, []).append(x)
...
>>> di[str], di[Number]
(['2', '4'], [1, 3, 5])
正如@PadraicCunningham 在评论中指出的那样,对于 Python 2,您可以使用 basestring
而不是 str
来捕获 Unicode 类型。