Проход по массиву int, возвращает True, если следующий int равен текущему - PullRequest
0 голосов
/ 10 октября 2019

Учитывая список целых чисел, вернуть True, если массив содержит 3 рядом с 3 где-то.

has_33 ([1, 3, 3]) → True

has_33 ([1, 3, 1, 3]) → Ложь

has_33 ([3, 1, 3]) → Ложь

Первый подход:

def has_33(nums):
    for i in range(0,len(nums)):
        return nums[i] == nums[i+1] ==3

Может кто-нибудь объяснитьмне что не так с этим подходом, я вижу, что этот код возвращает True, только если все элементы в списке истинны.

Второй подход:

def has_33(nums):
    for i in range(0,len(nums)):
        if(nums[i] == nums[i+1] ==3):
            return True

Второй подход удовлетворяет мой вопрос.

В чем разница между этими двумя подходами?

Ответы [ 2 ]

2 голосов
/ 10 октября 2019

Ну, разница довольно очевидна. В первом случае вы, безусловно, возвращаете результат выражения nums[i] == nums[i+1] ==3 независимо от значения этого выражения. На самом деле это означает, что вы всегда возвращаетесь к самой первой итерации, поэтому ваш код можно записать так:

def has_33(nums):
    if len(nums):
        return nums[0] == nums[1] ==3

Во втором случае вы вернете только, если выражение истинно, поэтому итерация продолжаетсяпока вы либо явно не вернете (не нашли совпадение), либо итерация естественным образом не завершится, и вы ничего не нашли (в этом случае функция неявно вернет None).

Несвязанный, но ваш код (вторая версия)можно улучшить несколькими способами. Первый пункт: цикл «for» в Python относится к типу «foreach» - вы итерируете элементы последовательности, а не индексы. Если вам не нужен индекс, правильный путь -

for item in iterable:
    do_something_with(item)

, здесь нет необходимости в range(len(xxx)) и индексированном доступе.

Если вам нужны и элемент, и индекс,тогда enumerate() ваш друг - он дает (index, item) кортежей:

for index, item in enumerate(sequence):
    print("item at {} is {}".format(index, item))

Теперь для вашей текущей потребности - получение (item, nextitem) пар - есть еще одно решение: zip(seq1, seq2) + нарезка:

for item, nextitem in zip(sequence, sequence[1:]):
    print("item: {} - nextitem : {}".format(item, nextitem))

и, наконец, если вы хотите проверить, удовлетворяет ли хотя бы один элемент последовательности условию, вы можете использовать any() с предикатом:

def has_33(nums):
    return any((item == nextitem == 3) for item, nextitem in zip(nums, nums[1:]))

Другое решениеможно было бы превратить nums в строку и найти в ней буквальную строку "33":

def has_33(nums):
    return "33" in "".join(str(x) for x in nums)

, но я не уверен, что это будет более эффективно (вы можете использовать timeit дляузнай сам).

0 голосов
/ 10 октября 2019

При первом подходе вы вернете значение

return nums[i] == nums[i+1] == 3 #Where i = 0 since it returns 
first iteration.
return nums[0]==nums[1] == 3 #If nums = [0,3,3]
return false # would be your result. But it would never check the next pair of values.

При втором подходе вернете значение

return true #If the if-statement is satisfied

Функция возврата завершит функциюзвони, когда звонят. Следовательно, если он вызывается в цикле for без оператора if, он будет вызван для первой итерации. Если есть оператор if и итерация проходит через оператор if, он вернет и завершит цикл на этой итерации. По сути, функция возврата завершает вызов функции и возвращает заданное значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...