重写zip功能不起作用

时间:2015-11-25 13:40:47

标签: python

我将zip函数改写为Python技能的练习。目的是使用列表理解来编写它,尽管我并不是100%确定我对它完全满意,因此我就是这样做的。

这是我到目前为止所做的:

def zip(l1, l2):
    return [(l1[0], l2[0])] + zip(l1[1:], l2[1:])

z = zip(['a', 'b', 'c'], [1,2,3])
for i in z: print(i)

这是我得到的错误,我不确定如何修复!

Traceback (most recent call last):
  File "path-omitted", line 47, in <module>
    z = zip(['a', 'b', 'c'], [1, 2,3])
  File "path-omitted", line 45, in zip
    return [(l1[0], l2[0])] + zip(l1[1:], l2[1:])
  File "path-omitted", line 45, in zip
    return [(l1[0], l2[0])] + zip(l1[1:], l2[1:])
  File "path-omitted", line 45, in zip
    return [(l1[0], l2[0])] + zip(l1[1:], l2[1:])
  File "path-omitted", line 45, in zip
    return [(l1[0], l2[0])] + zip(l1[1:], l2[1:])
IndexError: list index out of range

3 个答案:

答案 0 :(得分:7)

您的zip函数实现是递归的。在某些时候,l1[1:]l2[1:]将变为空,并且尝试访问第一个元素将失败并显示IndexError

检查l1l2是否都非空,如果是,则返回空列表:

def zip(l1, l2):
    if not (l1 and l2):
        return []
    return [(l1[0], l2[0])] + zip(l1[1:], l2[1:])

或者您可以抓住IndexError并返回[]

def zip(l1, l2):
    try:
        return [(l1[0], l2[0])] + zip(l1[1:], l2[1:])
    except IndexError:
        return []

答案 1 :(得分:2)

澄清一下,seq[1:]即使对于空序列也是合法的 - 你只需得到一个空的子序列。问题是当你尝试在下一个递归调用中取消引用零元素时。

通过确保在两个参数中的任何一个元素中耗尽元素时停止递归来修复代码。

另外,请注意Python不支持无限递归;将您的函数用于很长的列表,并且您将触发递归错误。但是(理论上)这不是代码的错误。

答案 2 :(得分:1)

不要使用递归,它会消耗比这更多的内存:

a = [1,2,3]
b = [4,5,6,7]

def zippy(a,b):
    try:
        return [(a[i],b[i]) for i, _ in enumerate(a)]
    except:
        pass

print zippy(a,b)

输出:

[(1, 4), (2, 5), (3, 6)]