问题
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