繁体   English   中英

Python:将长度为n的列表拆分为一个表,或者按类型将保留顺序列入更多列表

[英]Python : Split a list of length n into a table or further lists, by type, retaining order

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

['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

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

有一个更好的方法吗 ?

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

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] 

我可能会在这里采用一种稍微不同的方法,使用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中)或者在python 3.x中list(d.values())

>>> 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']]

由@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']]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM