Hold an object, using class in python

2019-03-03 11:50发布

问题:

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.



标签: python class