python CookBook 3 1.

发布时间:2019-07-12 10:01:08编辑:auto阅读(1189)

    问题:

       你需要从一个可迭代对象中拆解出N个元素,但是它可能多于N个元素并导致抛出“too many values to unpack”的异常


    解决:

       python的“带星参数”可以搞定这个问题。比如说,你开了一门课并且决定在期末的时候,你将去掉第一次和最后一次的家庭作业的成绩再计算出剩余的平均成绩。如果只有四次作业,那就是小意思妥妥的无压力秒杀。可如果是有24次作业呢? 带星参数将能很好地解决这个问题:


    def drop_first_last(grades):

       first, *middle, last = grades

       return avg(middle)


    另一个栗子,假设你有包含了用户名,邮箱及一坨长度任意的电话号码。你可以这么处理:

       P.S   python2.7.6会报错

    书上的例子有一处打印错

    >>> name, email, *phone_numbers = record
    >>> record = ('Dave', 'dave@example.com', '773-555-1212', '847-555-1212')
    >>> name, email, *phone_numbers = record #书上此处为 user_record
    >>> name
    'Dave'
    >>> email
    'dave@example.com'
    >>> phone_numbers
    ['773-555-1212', '847-555-1212']
    >>>


    无论有多少个要拆解或为None phones_number变量总会是一个列表,因此在对phones_number变量做处理时,无须做是否为列表的类型检查。(撒花!!)

    带星参数 也可用于列表开头。比如说,你有一个关于你公司过去8个季度的销售数据序列。如果你想知道最后一个季度与前七个季度的平均值相比哪个更好。你可以这么处理:

    *trailing_qtrs, current_qtr = sales_record

    trailing_avg = sum(trailing_qtrs) / len(trailing_qtrs)

    return avg_comparison(trailing_avg, current_qtr)


    栗子!栗子:

    >>> *trailing, current = [10, 8, 7, 1, 9, 5, 10, 3]
    >>> trailing
    [10, 8, 7, 1, 9, 5, 10]
    >>> current
    3
    >>>


    讨论:

       可扩展的迭代对象的拆解适用于拆解长度未知或任意的可迭代对象。经常的情况是这类可迭代对象的一些结构是已知的。带星参数可以方便让你访问到相关的元素。


    >>> records = [ ('foo', 1, 2), ('bar', 'hello'), ('foo', 3, 4)]
    >>> def do_foo(x, y):
        print('foo', x, y)
                                                                    
    >>> def do_bar(s):
        print('bar', s)
                                                                    
    >>> for tag, *args in records:
        if tag == 'foo':
            do_foo(*args)
        elif tag == 'bar':
            do_bar(*args)
                                                                        
    foo 1 2
    bar hello
    foo 3 4
    >>>

    带星的拆解 在诸如抄截字符串时也很有用。

    >>> line = 'nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false'
    >>> uname, *fields, homedir, sh = line.split(':')
    >>> uname
    'nobody'
    >>> homedir
    '/var/empty'
    >>> sh
    '/usr/bin/false'
    >>>


    有时,我会想干掉分离出来的元素。你不能就单单使用带星参数了,你可以使用一个常见的表示可抛弃的变量名 像是 ‘_’或者 ign(ignored)

    >>> record = ('ACME', 50, 123.45, (12, 18, 2012))
    >>> name, *_, (*_, year) = record
    >>> name
    'ACME'
    >>> year
    2012
    >>>


    列表:

    >>> items = [1, 10, 7, 4, 5, 9]
    >>> head, *tail = items
    >>> head
    1
    >>> tail
    [10, 7, 4, 5, 9]
    >>>


    有人会想到写个方法以便执行一些递归算法

    >>> def sum(items):
        head, *tail = items
        return head + sum(tail) if tail else head
    >>> sum(items)
    36
    >>>


关键字