可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I write a program to weave lists of floats together, for example:
l1 = [5.4, 4.5, 8.7]
l2 = [6.5, 7.8]
l3 = [6.7, 6.9]
I want to weave l1 into l2:
[5.4, 6.5, 4.5, 7.8, 8.7]
And now I want it in a class so I can hold this result and weave l3 into it:
[5.4, 6.7, 6.5, 6.9, 4.5, 7.8, 8.7]
The function I wrote two weave two lines together is:
def Weave_number_rows(row1,row2): #enter 2 rows of numbers as lists
l1 = row1
l2 = row2
woven = sum(zip(l1, l2), ())
print woven
How to hold the result with a class and weave the next line into it?
回答1:
Your weave function drops the last element of l2
; you need to use itertools.zip_longest()
here:
try:
from itertools import zip_longest
except ImportError:
# Python 2
from itertools import izip_longest as zip_longest
def weave_rows(row1, row2):
return [v for v in sum(zip_longest(row1, row2), ()) if v is not None]
Note that you need to return, not print, your output. The izip_longest()
call adds None
placeholders, which we need to remove again from the sum()
output after zipping.
Now you can simply weave in a 3rd list into the output of the previous two:
weave(weave(l1, l2), l3)
Demo:
>>> weave_rows(l1, l2)
[5.4, 6.5, 4.5, 7.8, 8.7]
>>> weave_rows(weave_rows(l1, l2), l3)
[5.4, 6.7, 6.5, 6.9, 4.5, 7.8, 8.7]
回答2:
Another solution (based on Martijn Pieters code) which avoids recursion is:
try:
from itertools import zip_longest
except ImportError:
# Python 2
from itertools import izip_longest as zip_longest
def weave_two(row1, row2):
return [v for v in sum(zip_longest(row1, row2, fillvalue=None), ()) if v is not None]
def weave_rows(*args):
if len(args) < 2:
return None
current = weave_two(args[0], args[1])
for i in range(2, len(args)):
current = weave_two(current, args[i])
return current
usage:
>>> weave_rows(l1, l2, l3)
[5.4, 6.7, 6.5, 6.9, 4.5, 7.8, 8.7]
回答3:
Function you wrote returns None
, as no return statement is present. Replace print
with return
and chain calls. You might also need izip_longest
instead of zip for lists of nonequal size:
With izip_longest:
from itertools import izip_longest
def weave(l1, l2):
return filter(None, sum(izip_longest(l1, l2), ())
demo
>>> weave(weave(l1, l2), l3)
(5.4, 6.7, 6.5, 6.9, 4.5, 7.8, 8.7)
Without, zip breaks on shortest argument:
>>> def weave_shortest(l1, l2):
return sum(zip(l1, l2), ())
>>> weave_shortest(l3, weave_shortest(l1, l2))
(5.4, 6.7, 6.5, 6.9)
回答4:
OK, as peoples comments, this seems a strange case to start using classes but something like this should work:
from itertools import zip_longest
class Weaver():
def __init__(self,data):
self.result = data
def weave(data):
self.result = sum(zip_longest(self.result, data),()) # or whatever version
# works best from
# the other answers
w = Weaver(l1)
w.weave(l2)
w.weave(l3)
print(w.result)
This creates a Weaver
object w
and initialises it with l1
. Then you weave the other lists in one by one and it stores the result internally and finally you access and print that result.