Python - 仅包含数据的zip列表

时间:2016-01-27 16:00:22

标签: python list python-3.x zip

我有一个脚本可以将数据从一种类型转换为另一种类型。 源文件可以包含一个,两个或全部:位置,旋转和缩放数据。

在输出文件进行转换后,我的脚本将3压缩在一起。

在这种情况下,我的源文件只包含位置数据。 所以最后返回的列表是:

pData = [['-300.2', '600.5'],['150.12', '280.7'],['19.19', '286.56']]
rData = []
sData = []

translationData = list(zip(pData, rData, sData))

如果我尝试这样做,它会返回[],因为最短的列表是[]。 如果我尝试:

translationData = list(zip_longest(pData, rData, sData))

我明白了:

`[(['-300.2', '600.5'], None, None), (['150.12', '280.7'], None, None), (['19.19', '286.56'], None, None)]`

有没有办法只压缩包含数据的列表,或从列表中的元组中删除None

提前致谢!

6 个答案:

答案 0 :(得分:3)

您可以使用list-comp中嵌入的filter内置。

  

注意:在Python 3 filter中返回一个迭代器,因此您需要在其上调用tuple()。 (与py2不同)

pData = [['-300.2', '600.5'],['150.12', '280.7'],['19.19', '286.56']]
rData = []
sData = []

from itertools import zip_longest  # izip_longest for python 2
[tuple(filter(None, col)) for col in zip_longest(pData, rData, sData)]

结果:

[(['-300.2', '600.5'],), (['150.12', '280.7'],), (['19.19', '286.56'],)]

答案 1 :(得分:0)

我会尝试添加更多变体 - boolNonelambda

import itertools
from itertools import zip_longest
pData = [['-300.2', '600.5'],['150.12', '280.7'],['19.19', '286.56']]
rData = []
sData = []


print ([list(filter(bool, col)) for col in zip_longest(pData, rData, sData)])
print ([list(filter(None, col)) for col in zip_longest(pData, rData, sData)])
print ([list(filter(lambda x: x, col)) for col in zip_longest(pData, rData, sData)])

输出 -

[[['-300.2', '600.5']], [['150.12', '280.7']], [['19.19', '286.56']]]
[[['-300.2', '600.5']], [['150.12', '280.7']], [['19.19', '286.56']]]
[[['-300.2', '600.5']], [['150.12', '280.7']], [['19.19', '286.56']]]

答案 2 :(得分:0)

您可以在给定documentation的情况下修改zip_longest的纯Python版本,并创建一个版本以执行您想要的操作:

from itertools import chain, repeat

class ZipExhausted(Exception):
    pass

def zip_longest(*args, **kwds):
    # zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
    fillvalue = kwds.get('fillvalue')
    counter = len(args) - 1
    def sentinel():
        nonlocal counter
        if not counter:
            raise ZipExhausted
        counter -= 1
        yield fillvalue
    fillers = repeat(fillvalue)
    iterators = [chain(it, sentinel(), fillers) for it in args]
    try:
        while iterators:
            res = []
            for it in iterators:
                value = next(it)
                if value != fillvalue:
                    res.append(value)
            yield tuple(res)
    except ZipExhausted:
        pass

pData = [['-300.2', '600.5'],['150.12', '280.7'],['19.19', '286.56']]
rData = []
sData = []

translationData = list(zip_longest(pData, rData, sData))
print(translationData)

输出:

[(['-300.2', '600.5'],), (['150.12', '280.7'],), (['19.19', '286.56'],)]

答案 3 :(得分:0)

如果您由于某种原因不想导入或使用列表推导等:

  1. 对要压缩的列表(allLists)进行分组
  2. 然后循环分组以检查每个
  3. 中是否有任何内容
  4. 将包含数据的组合(zippable)附加在一起
  5. 最后,*传递zip过滤分组(* zippable)

    alist = ['hoop','joop','goop','loop']
    blist = ['homp','jomp','gomp','lomp']
    clist = []
    dlist = []
    
    allLists = [alist,blist,clist,dlist]
    
    zippable = []
    
    for fullList in allLists:
        if fullList:
            zippable.append(fullList)
    
    finalList = list(zip(*zippable))
    
    print(finalList)
    
  6. 另一种可能的解决方案

答案 4 :(得分:0)

如果列表完全为空或完全填满,则可以使用:

>>> list(zip(*(x for x in (pData, rData, sData) if x)))
[(['-300.2', '600.5'],), (['150.12', '280.7'],), (['19.19', '286.56'],)]

答案 5 :(得分:0)

如果您不想要None,可以使用zip_longest的关键字参数fillvalue来放置您想要的任何内容,这样您就可以获得统一的结果出自@Ale

>>> translationData = list(zip_longest(pData, rData, sData, fillvalue=tuple()))
>>> translationData
[(['-300.2', '600.5'], (), ()), (['150.12', '280.7'], (), ()), (['19.19', '286.56'], (), ())]
>>> 

请注意,如果您使用可变对象作为填充值,因为如果您更改了一个,则所有这些都会更改,因为它们都是对同一对象的引用

>>> translationData = list(zip_longest(pData, rData, sData,fillvalue=list()))
>>> translationData
[(['-300.2', '600.5'], [], []), (['150.12', '280.7'], [], []), (['19.19', '286.56'], [], [])]
>>> translationData[0][1].append(23)
>>> translationData
[(['-300.2', '600.5'], [23], [23]), (['150.12', '280.7'], [23], [23]), (['19.19', '286.56'], [23], [23])]
>>>