白piao系列その一

16 篇文章 0 订阅
3 篇文章 0 订阅

写在前面

前两天看到了国外大佬写的文章,就关注他了,在他的网站注册了,获得了一个月四次的免费练习机会,原价是一个月$20,一个月140rmb, 一道题35块,真的太贵了, 买是买不起, 只能白嫖了。

用了差不多一个下午,断断续续地写出来了,写出来感觉很有成就感,虽然知道代码结构很乱,又不精简。看到大佬最终的代码,虽然有心理准备,但是瞬间觉得,自己写出了一推shit,好在和大佬的思路基本是相似, 最关键的就是又zip()函数。

我知道,现在对于我现在来说, 还是刷面试题更重要更实际些, 可是没忍住, 花了很长时间, 阅读分析了大佬的教程,,

 

题目描述

Assigned from Mixed Level on 08/30/2019

Hey! ✨

I'd like you to write a function that accepts two lists-of-lists of numbers and returns one list-of-lists with each of the corresponding numbers in the two given lists-of-lists added together.

It should work something like this:

>>> matrix1 = [[1, -2], [-3, 4]]
>>> matrix2 = [[2, -1], [0, -1]]
>>> add(matrix1, matrix2)
[[3, -3], [-3, 3]]
>>> matrix1 = [[1, -2, 3], [-4, 5, -6], [7, -8, 9]]
>>> matrix2 = [[1, 1, 0], [1, -2, 3], [-2, 2, -2]]
>>> add(matrix1, matrix2)
[[2, -1, 3], [-3, 3, -3], [5, -6, 7]]

Try to solve this exercise without using any third-party libraries (without using pandas for example).

Before attempting any bonuses, I'd like you to put some effort into figuring out the clearest and most idiomatic way to solve this problem.

There are two bonuses this week.

For the first bonus, modify your add function to accept and "add" any number of lists-of-lists. ✔️

>>> add([[1, 9], [7, 3]], [[5, -4], [3, 3]], [[2, 3], [-3, 1]])
[[8, 8], [7, 7]]

For the second bonus, make sure your add function raises a ValueError if the given lists-of-lists aren't all the same shape. ✔️

>>> add([[1, 9], [7, 3]], [[1, 2], [3]])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "add.py", line 10, in add
    raise ValueError("Given matrices are not the same size.")
ValueError: Given matrices are not the same size.

 

我写出的shit

# m1 = [[1, -2, 4], [-3, 4, 1, 3], [1, 1, 1]]
# m2 = [[2, -1, 1], [0, -1, 1, 4], [1, 1, 1]]
# m3 = [[2, -1, 1], [0, -1, 1, 6], [1, 1, 1]]
# m4 = [[1, -2, 1], [-3, 4, 1, 3], [1, 1, 1]]
# m5 = [[1, -2, 1], [-3, 4, 1, 3], [1, 1, 1]]


def add(*args):
    lens = len(args)                  # 统计参数个数,然后按参数个数,循环几次
    ll = [[] for i in range(lens)]
    count = 0
    for z in args:
        for i in z:
            ll[count].append(len(i))
        count += 1
    # ll [[3, 4, 3], [3, 4, 3], [3, 4, 3], [3, 4, 3], [3, 4, 3]] 统计每个参数的长度
    for i in range(lens-1):
        if ll[i] != ll[i+1]:
            raise ValueError("Given matrices are not the same size.")
    a = zip(*args)
    l1 = []
    for i in a:
        l1.append(i)
    # [([1, -2, 1], [2, -1, 1]), ([-3, 4, 1], [0, -1, 1]), ([1, 1, 1], [1, 1, 1])]
    # [[[1, -2, 1], [2, -1, 1]], [[-3, 4, 1], [0, -1, 1]], [[1, 1, 1], [1, 1, 1]]]   加list
    k = []
    klens = len(args[0])         # 一个参数的长度
    for i in range(klens):
        k.append(list(eval('zip' + str(l1[i]))))
    # [[(1, 2), (-2, -1), (1, 1)], [(-3, 0), (4, -1), (1, 1)], [(1, 1), (1, 1), (1, 1)]]
    result = []
    for i in k:
        y = list(map(sum, i))
        result.append(y)
    #  [[3, -3, 2], [-3, 3, 2], [2, 2, 2]]
    return result

 

下面跟着大佬一点点来的

 

一 满足第一个条件(即只有两个参数)

1 常规操作

def add(matrix1, matrix2):
    """Add corresponding numbers in given 2-D matrices."""
    combined = []
    for rows in zip(matrix1, matrix2):
        # 循环的是这个 [([1, -2, 1], [2, -1, 1]), ([1, 1, 1], [1, 1, 1])]
        row = []
        for items in zip(rows[0], rows[1]):
            # 循环的大概是 [(1, 2), (-2, -1), (1, 1)]
            row.append(items[0] + items[1])
        # print("xxx", row)
        # [3, -3, 2]
        # [2, 2, 2]
        combined.append(row)
    return combined

2. for 多个值

def add(matrix1, matrix2):
    """Add corresponding numbers in given 2-D matrices."""
    combined = []
    for row1, row2 in zip(matrix1, matrix2):
        """
        一组情况 打印 row1 row2
        [1, -2, 1]
        [2, -1, 1]
        """
        row = []

        for n, m in zip(row1, row2):
            # 循环的大概是 [(1, 2), (-2, -1), (1, 1)]
            """
            一组情况打印 n m
            1
            2
            """
            row.append(n + m)
        combined.append(row)
    return combined

3 使用列表推导式, 省掉定义的额外空间

def add(matrix1, matrix2):
    """Add corresponding numbers in given 2-D matrices."""
    combined = []
    for row1, row2 in zip(matrix1, matrix2):
        row = [
            n + m
            for n, m in zip(row1, row2)
        ]
        combined.append(row)
        # row 是个列表, 加到combined也是个列表
    return combined

4 直接加到例表里, 连row变量都省了

def add(matrix1, matrix2):
    """Add corresponding numbers in given 2-D matrices."""
    combined = []
    for row1, row2 in zip(matrix1, matrix2):
        combined.append([
            n + m
            for n, m in zip(row1, row2)
        ])
    return combined

5 下面倒是没啥, 写到一行,增加代码可读性

def add(matrix1, matrix2):
    """Add corresponding numbers in given 2-D matrices."""
    combined = []
    for row1, row2 in zip(matrix1, matrix2):
        combined.append([n + m for n, m in zip(row1, row2)])
    return combined

6 下面又省了一个列表变量, 真TM秀

def add(matrix1, matrix2):
    """Add corresponding numbers in given 2-D matrices."""
    return [
        [n + m for n, m in zip(row1, row2)]
        for row1, row2 in zip(matrix1, matrix2)
    ]

7 再写写成一行

def add(matrix1, matrix2):
     """Add corresponding numbers in given 2-D matrices."""
     return [[n+m for n, m in zip(r1, r2)] for r1, r2 in zip(matrix1, matrix2)]

以上, 一行代码, 写出了, 只有两个参数的情况。

 

二 满足第二个条件(可以输入多个参数)

1 常规操作

def add(*matrices):
    """Add corresponding numbers in given 2-D matrices."""
    combined = []
    for rows in zip(*matrices):
        row = []
        """
        rows
        ([1, -2, 1], [2, -1, 1])
        ([1, 1, 1], [1, 1, 1])
        * rows
        [1, -2, 1] [2, -1, 1]
        [1, 1, 1] [1, 1, 1]
        """

        for values in zip(*rows):
            # 上面打印的*rows, 没逗号, 但是zip可以直接用.
            # print(values)
            """
            大概是这种
            (1, 2)
            (-2, -1)
            (1, 1)
            """
            total = 0
            for n in values:
                total += n
            row.append(total)
        combined.append(row)
    return combined

2 用sum, 

def add(*matrices):
    """Add corresponding numbers in given 2-D matrices."""
    combined = []
    for rows in zip(*matrices):
        row = []
        for values in zip(*rows):
            row.append(sum(values))
        combined.append(row)
    return combined

3 最后再精简

def add(*matrices):
    """Add corresponding numbers in given 2-D matrices."""
    return [
        [sum(values) for values in zip(*rows)]
        for rows in zip(*matrices)
    ]

以上です。

三 满足第三个条件(数据机构不对,触发异常)

If we ignored our first bonus, we could do this:

1. 利用列表的深度比较, 直接比较

忽略第二个条件, 就是先只给它传两个参数

def add(matrix1, matrix2):
    """Add corresponding numbers in given 2-D matrices."""
    if [len(r) for r in matrix1] != [len(r) for r in matrix2]:
        raise ValueError("Given matrices are not the same size.")
    return [
        [n + m for n, m in zip(row1, row2)]
        for row1, row2 in zip(matrix1, matrix2)
    ]

2. If we use tuples instead of lists, we could use a set for this 但是要用集合, 就相对繁琐些, 因为集合没有深度比较, 如果有疑问可以看https://blog.csdn.net/DeskyAki/article/details/100160599

def add(*matrices):
    """Add corresponding numbers in given 2-D matrices."""
    matrix_shapes = {
        tuple(len(r) for r in matrix)
        for matrix in matrices
    }
    if len(matrix_shapes) > 1:
        raise ValueError("Given matrices are not the same size.")
    return [
        [sum(values) for values in zip(*rows)]
        for rows in zip(*matrices)
    ]

3. 使用集合的另一种方法, 用到了zip_logest() 与zip()相似, 只是它以最长的元素为标准, 详情看python复习

from itertools import zip_longest


def add(*matrices):
    """Add corresponding numbers in given 2-D matrices."""
    try:
        return [
            [sum(values) for values in zip_longest(*rows)]
            for rows in zip_longest(*matrices)
            # rows大概是这种感觉([2, -1, 1], None, None)], 再zip因为有None,会报错
        ]
    except TypeError as e:
        raise ValueError("Given matrices are not the same size.") from e

4. 牛B的最终版

def get_shape(matrix):
    return [len(r) for r in matrix]


def add(*matrices):
    """Add corresponding numbers in given 2-D matrices."""
    shape_of_matrix = get_shape(matrices[0])
    # matrices[0]第一个参数  第一个参数的所有项的长度[3, 3]
    if any(get_shape(m) != shape_of_matrix for m in matrices):
        # 这个逻辑有些绕, any是说, 只有所有的都是False,才返回False,即 != 都是False, 才不会除法这个if 条件,,很绕啊,,
        raise ValueError("Given matrices are not the same size.")
    return [
        [sum(values) for values in zip(*rows)]
        for rows in zip(*matrices)
    ]

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值