Hold an object, using class in python

2019-03-03 12:01发布

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?

标签: python class
4条回答
成全新的幸福
2楼-- · 2019-03-03 12:15

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.

查看更多
劫难
3楼-- · 2019-03-03 12:25

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]
查看更多
Summer. ? 凉城
4楼-- · 2019-03-03 12:26

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]
查看更多
干净又极端
5楼-- · 2019-03-03 12:28

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)
查看更多
登录 后发表回答