3

本质上,我有一个项目列表,每个项目都有不同的类型,例如

['a',1,'b',2,3,'c'] 

或者

[{"A":1},1,{"B":2},{"C":3},"a"]

我想将它们分成两个单独的列表,保留原始顺序

[[ 'a', None,  'b', None, None,  'c'],
 [None,    1, None,    2,    3, None]]

或者

[[{"A":1}, None, {"B":2},{"C":3}, None],
 [None,       1,    None,   None, None],
 [None,    None,    None,   None,  "a"]]

是)我有的 :

def TypeSplit(sources)
  Types = [dict(),str(),num()]
  return [[item for item in sources if type(item) == type(itype)] for itype in types]  

虽然这没有填写None

我这样做的原因是我将获得一个包含不同类型信息的列表,并且需要用其他与原始列表相得益彰的值来充实它。

有一个更好的方法吗 ?

4

4 回答 4

2

这是条件表达式的一个很好的用例。另外,我假设您希望以尽可能通用的方式执行此操作,因此我建议您动态生成列表,而不是使用固定的类型列表:

def type_split(sources):
    types = sorted(set(type(i) for i in sources))
    return [[item if type(item) == itype else None for item in sources] 
            for itype in types]  

如果您需要使用固定列表(并且您知道您的输入列表将不包含这些类型及其子类之外的任何内容),您可以这样做:

import collections
import numbers
def type_split(sources):
    types = [basestring, collections.Mapping, numbers.Number]
    return [[item if isinstance(item, itype) else None for item in sources] 
            for itype in types] 
于 2012-07-25T13:06:12.913 回答
2

我可能会在这里使用稍微不同的方法defaultdict

from collections import defaultdict
def type_split(sources):
   d=defaultdict(lambda : [None]*len(sources))
   for i,src in enumerate(sources):
       d[type(src)][i] = src
   return d

这将返回字典而不是列表,但更容易内省各种元素的类型...如果您真的想要列表列表,您可以随时查看d.values()(在 python2.x 中)或list(d.values())在 python 3 中。 X

于 2012-07-25T13:18:04.520 回答
1
>>> def type_split(seq, types): 
        return [[x if isinstance(x, t) else None for x in seq] for t in types]

>>> type_split(['a',1,'b',2,3,'c'], (str, int))
[['a', None, 'b', None, None, 'c'], [None, 1, None, 2, 3, None]]
>>> type_split([{"A":1},1,{"B":2},{"C":3},"a"], (dict, int, str))
[[{'A': 1}, None, {'B': 2}, {'C': 3}, None], [None, 1, None, None, None], [None, None, None, None, 'a']]
于 2012-07-25T13:20:22.627 回答
1

@mgilson 对解决方案的改编,将类型的原始顺序保留为有序键。

>>> from collections import OrderedDict
>>> def type_split(seq):
        d = OrderedDict()
        for i, x in enumerate(seq):
            d.setdefault(type(x), [None] * len(seq))[i] = x
        return d.values()

>>> type_split(['a',1,'b',2,3,'c'])
[['a', None, 'b', None, None, 'c'], [None, 1, None, 2, 3, None]]
>>> type_split([{"A":1},1,{"B":2},{"C":3},"a"])
[[{'A': 1}, None, {'B': 2}, {'C': 3}, None], [None, 1, None, None, None], [None, None, None, None, 'a']]
于 2012-07-25T14:04:04.710 回答