Python - 列出操作练习

时间:2018-05-07 16:45:00

标签: python list

问题:

  

编写一个程序,搜索列表以查找第一个奇数。如果找到奇数,则找到奇数后面的第一个偶数。返回第一个奇数和第一个偶数之间的距离。如果没有找到奇数,或者在奇数后面没有偶数,则返回-1。

我的代码:

def go(list1):
    dist = 0
    odd = 0
    even = 0
    for i in range(0,len(list1)):
        if list1[i] % 2 == 1:
            odd = list1[i]
            break
        else:
            odd = list1[0]
    list2 = list1[list1.index(odd)+1:]
    for i in range(0,len(list2)):
        if list2[i] % 2 == 0:
            even = list2[i]
            break
        else:
            even = list2[0]
    return list2.index(even) + list1.index(odd) + 1 - list1.index(odd)

print(go([7,1,5,3,11,5,6,7,8,9,10,12345,11]))
print(go([11,9,8,7,6,5,4,3,2,1,-99,7]))
print(go([10,20,30,40,5,41,31,20,11,7]))
print(go([32767,70,4,5,6,7]))
print(go([2,7,11,21,5,7]))
print(go([7,255,11,255,100,3,2]))
print(go([9,11,11,11,7,1000,3]))
print(go([7,7,7,11,2,7,7,11,11,2]))
print(go([2,4,6,8,8]))

我的输出:

6
2
3
1
1
4
5
4
1

期望的输出:

6
2
3
1
-1
4
5
4
-1

我做错了什么?对于这个问题,有没有比我做的更好的方法?

6 个答案:

答案 0 :(得分:5)

您可以使用iterator来解决此问题。

迭代器是一个"记住"它目前在列表中的位置。创建迭代器时,它指向列表中的第一个元素。然后,您可以使用next函数向前移动迭代器。

所以这个想法是这样的:

  1. 创建迭代器
  2. 向前移动迭代器,直到找到第一个奇数
  3. 进一步向前移动,直至找到偶数,计算步骤
  4. 在第3步中,enumerate函数对于计算迭代器跳过的元素数非常有用。

    def go(iterable):
        # step 1: get an iterator for this iterable
        itr = iter(iterable)
        try:
            # step 2: advance the iterator to the first odd number
            next(num for num in itr if num % 2 == 1)
    
            # step 3: count the elements up to the next even number
            return next(i for i, num in enumerate(itr, 1) if num % 2 == 0)
        except StopIteration:
            # StopIteration is raised if the iterator reaches the end without
            # finding a suitable number
            return -1
    

答案 1 :(得分:4)

您的错误是:

  • 如果你找不到偶数或奇数,你就取第一个元素而不是返回-1。
  • 要计算距离,您不能减去list1.index(odd)(只需删除此部分,方程式正确)

您应该存储以下位置:

,而不是存储值并创建新列表
def go(list1):
    odd = None
    even = None
    for i in range(0,len(list1)):
        if list1[i] % 2 == 1:
            odd = i
            break

    if odd is not None:
        for i in range(odd, len(list1)):
            if list1[i] % 2 == 0:
                even = i
                break

    if odd is None or even is None:
        return -1
    else:
        return even - odd

这是一个更加pythonic的版本:

def go(list1):
    try:
        odd = next(i for (i, v) in enumerate(list1) if v % 2 == 1)
        even = next(i for (i, v) in enumerate(list1) if v % 2 == 0 and i > odd)
        return even - odd
    except StopIteration:
        return -1

StopIteration是下一个到达列表末尾时没有任何匹配值的异常。

答案 2 :(得分:0)

回答错误我认为使用你的“其他”陈述:

else:
    even = list2[0]

如果找不到任何偶数,为什么要从列表中指定一个数字?这就是你的距离= 1

的原因

同样的事情:

 else:
        odd = list1[0]

如果找不到,则不应将数字指定为奇数。

答案 3 :(得分:0)

我会做这样的事情:

def go(list1):
    dist = 0
    found = False;
    for i in range(0,len(list1)):
        if list1[i] % 2 == 1:
          for j in range(i,len(list1)):
            if list1[j] % 2 == 0:
             found = True;
             return(j-i)
             break
    if(found == False):
      return -1;

print(go([7,1,5,3,11,5,6,7,8,9,10,12345,11]))
print(go([11,9,8,7,6,5,4,3,2,1,-99,7]))
print(go([10,20,30,40,5,41,31,20,11,7]))
print(go([32767,70,4,5,6,7]))
print(go([2,7,11,21,5,7]))
print(go([7,255,11,255,100,3,2]))
print(go([9,11,11,11,7,1000,3]))
print(go([7,7,7,11,2,7,7,11,11,2]))
print(go([2,4,6,8,8]))

我看到你的代码中的主要问题是你默认使用列表中的第一个元素而不是默认为-1,如果找不到奇数或甚至没有。你永远不会检查是否找不到它。

我在代码中添加了一个布尔值,用于检查我们是否找到了该元素。代码完全没有布尔值,但我添加它以表明我们想要检查我们是否找到了奇数和偶数元素。如果我们找不到它:我们返回-1。否则:我们返回差异。

答案 4 :(得分:0)

这与其他评论者通过存储偶数和奇数的索引所建议的类似:

def go(list1):
    dist = 0
    odd_idx = None
    even_idx = None
    for i in range(len(list1)):
        if list1[i] % 2 == 1:
            odd_idx = i
            break
    if odd_idx is None:
        return -1

    list2 = list1[odd_idx+1:]
    for i in range(len(list2)):
        if list2[i] % 2 == 0:
            even_idx = i
            break
    if even_idx is None:
        return -1
    return abs(even_idx - odd_idx + 1)

print(go([7,1,5,3,11,5,6,7,8,9,10,12345,11]))
print(go([11,9,8,7,6,5,4,3,2,1,-99,7]))
print(go([10,20,30,40,5,41,31,20,11,7]))
print(go([32767,70,4,5,6,7]))
print(go([2,7,11,21,5,7]))
print(go([7,255,11,255,100,3,2]))
print(go([9,11,11,11,7,1000,3]))
print(go([7,7,7,11,2,7,7,11,11,2]))

希望这有帮助!

答案 5 :(得分:0)

您的代码中存在多个错误,这些错误共同导致您的代码永远不会返回-1。如果你传入一个空列表,它甚至会抛出ValueError

第一个问题是,如果您没有找到奇数,请指定odd = list1[0]。在没有奇数的情况下这是错误的。然后list2将包含list1中第一个数字以外的所有内容。同样,如果在第一个奇数之后没有偶数,则分配even = list2[0]

如果您正在寻找一对号码,您的功能是正确的。但是,您的退货声明可以简化为list2.index(even)+1

此外,在python中,您可以使用for x in lst语句循环遍历列表。如果您想要访问当前正在查看的元素的索引,请使用enumerate这样的

for i, x in enumerate(lst)

最后,这是解决问题的一种最简单的方法,我可以想到只需要列表的一次迭代。

def go(lst):
    odd_index = -1  # Index of the first odd number in the list

    for i, n in enumerate(lst):
        if n % 2 == 1:
            # n is odd
            if odd_index == -1:
                # This is the first even number we found, so we assign
                # its index to odd_index and look for an even number
                odd_index = i
        else:
            # n is even
            if odd_index != -1:
                # We already found odd number, so this is the
                # first even number and we can return
                return i - odd_index

    # The search was not successful, so we return -1
    return -1