Ну, разница довольно очевидна. В первом случае вы, безусловно, возвращаете результат выражения 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
дляузнай сам).