问题
There is an existing thread about this Zipping unequal lists in python in to a list which does not drop any element from longer list being zipped
But it's not quite I'm after.
Instead of returning None, I need it to copy the previous entry on the list.
Is this possible?
a = ["bottle","water","sky"]
b = ["red", "blue"]
for i in itertools.izip_longest(a,b):
print i
#result
# ('bottle', 'red')
# ('water', 'blue')
# ('sky', None)
# What I want on the third line is
# ('sky', 'blue')
回答1:
itertools.izip_longest takes an optional fillvalue argument that provides the value that is used after the shorter list has been exhausted. fillvalue defaults to None, giving the behaviour you show in your question, but you can specify a different value to get the behaviour you want:
fill = a[-1] if (len(a) < len(b)) else b[-1]
for i in itertools.izip_longest(a, b, fillvalue=fill):
print i
(Obviously if the same list is always the shorter one then choosing the fill character is even easier.)
回答2:
You can chain the shorter list with a repeat of its last value. Then using regular izip, the result will be the length of the longer list:
from itertools import izip, repeat, chain
def izip_longest_repeating(seq1, seq2):
if len(seq1) < len(seq2):
repeating = seq1[-1]
seq1 = chain(seq1, repeat(repeating))
else:
repeating = seq2[-1]
seq2 = chain(seq2, repeat(repeating))
return izip(seq1, seq2)
print(list(izip_longest_repeating(a, b)))
# [('bottle', 'red'), ('water', 'blue'), ('sky', 'blue')]
And here's a version that should work for any iterables:
from itertools import izip as zip # Python2 only
def zip_longest_repeating(*iterables):
iters = [iter(i) for i in iterables]
sentinel = object()
vals = tuple(next(it, sentinel) for it in iters)
if any(val is sentinel for val in vals):
return
yield vals
while True:
cache = vals
vals = tuple(next(it, sentinel) for it in iters)
if all(val is sentinel for val in vals):
return
vals = tuple(old if new is sentinel else new for old, new in zip(cache, vals))
yield vals
list(zip_longest_repeating(['a'], ['b', 'c'], ['d', 'r', 'f']))
# [('a', 'b', 'd'), ('a', 'c', 'r'), ('a', 'c', 'f')]
来源:https://stackoverflow.com/questions/55846806/using-zip-longest-on-unequal-lists-but-repeat-the-last-entry-instead-of-returnin