我有一个脚本可以将数据从一种类型转换为另一种类型。 源文件可以包含一个,两个或全部:位置,旋转和缩放数据。
在输出文件进行转换后,我的脚本将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
?
提前致谢!
答案 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)
我会尝试添加更多变体 - bool
,None
,lambda
。
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)
如果您由于某种原因不想导入或使用列表推导等:
最后,*传递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)
另一种可能的解决方案
答案 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])]
>>>