Почему возвращает пустой список?

Почему возвращает пустой список?

def count_smileys(arr):
    stack = []
    for i in range(len(arr)):
        for j in range(i):
            if arr[i][j] == ":" or arr[i][j] == ";":
                stack.append(arr[i][j])
            elif arr[i][j] == "~" or arr[i][j] == "-":
                if stack == 0:
                    return False
                else:
                    stack.append(arr[i][j])
            elif arr[i][j] == "D" or arr[i][j] == ")":
                if stack == 0:
                    return False
                else:
                    stack.append(arr[i][j])
        return stack

print(count_smileys([':D',':~)',';~D',':)']))         #, 4
print(count_smileys([':)',':(',':D',':O',':;']))      #, 2
print(count_smileys([';]', ':[', ';*', ':$', ';-D'])) #, 1

Ответы (4 шт):

Автор решения: MarianD

Первая ошибка здесь:

        for j in range(i):

должно быть

        for j in range(len(arr[i])):

Вторая в обоих

            if stack == 0:

т.к. это всегда будет False, потому что вы в начале определили stack как список.
Может быть, вы хотели

            if stack == []          # когда список пустой

Третья ошибка:

            return False

т.к. этим все заканчивается — функция возвратит False а никаких дальнейших проходов циклами не будет.

Я написал только 3 ошибки, но это не все. По моему надо сделать все заново, по-другому.

→ Ссылка
Автор решения: MarianD

Вы, наверно, хотите подсчитать количество смайликов в данном списке строк.

Притом смайлик для вас значит:

  • строку из 2 или 3 символов, в которой
    • первым знаком будет : или ;
    • второй знак может быть - или ~, но его можно пропустить,
    • последний знак должен быть D или )

Вы хотите подсчитать смайлики — начинаем с нуля:

def count_smileys(arr):
    counter = 0

Выбираем очередную строку из списка:

    for strn in arr:

Определим количество символов в ней:

        num_char = len(strn)

Когда оно не подходит, бросим эту строку — просто продолжаем проходить циклом, выбирая следующую строку:

        if num_char not in (2, 3):
            continue

Когда команда continue не выполнилась, знаем, что наша строка состоит из 2 или 3 символов. Когда первой из них нет : или ;, опять строку бросим:

        if strn[0] not in ":;":
            continue

То же самое с последним символом:

        if strn[-1] not in "D)":
            continue

Но и теперь всё зависит от количества символов — когда их в строке только 2, это смайлик, повисим количество смайликов и продолжаем работать со следующей строкой:

        if num_char == 2:
           counter += 1
           continue

Когда это не случилось знаем, что количество символов равно 3, 1-й и последний подходит, значит, всё зависит от среднего (2-го, т.е. с индексом 1):

        if strn[1] not in "-~":
            continue

Когда мы до сих пор не бросили строку, она подходит — это смайлик — и подсчитаем её:

        counter += 1

После окончания тестирования строк — выхода из цикла — в переменной counter уже количество всех смайликов, и мы ее возвратим:

    return counter

Всё.


Вся функция:

def count_smileys(arr):
    counter = 0

    for strn in arr:
        num_char = len(strn)
 
        if num_char not in (2, 3):
            continue
        if strn[0] not in ":;":
            continue
        if strn[-1] not in "D)":
            continue
        if num_char == 2:
            counter += 1
            continue
        if strn[1] not in "-~":
            continue

        counter += 1
    return counter

Тестировка с вашими списками:

print(count_smileys([':D',':~)',';~D',':)']))         #, 4
print(count_smileys([':)',':(',':D',':O',':;']))      #, 2
print(count_smileys([';]', ':[', ';*', ':$', ';-D'])) #, 1

выдаст

4
2
1
→ Ссылка
Автор решения: MarianD

Ваша задача как сделана для применения регулярки:

import re

def count_smileys(arr):
    counter = 0

    pattern = re.compile(r"[:;][-~]?[D)]$")

    for strn in arr:
        if pattern.match(strn):
            counter += 1
            
    return counter

В регулярном выражении

[:;][-~]?[D)]$
  • [:;] значит, что первым символом должно быть двоеточие или точка с запятой,
  • [-~]? значит, что следующий символ должен быт - или ~, или его возможно пропустить (?)
  • [D)] значит D или )
  • $ значит конец строки.

pattern.match(strn) сравняет начало строки strn c этим регулярным выражением.

→ Ссылка
Автор решения: hellog888
import re
def count_smileys(arr):
    buffer = [''.join(re.findall(r"[:;][-~]?[D)]$", x)) for x in arr]
    return len([x for x in buffer if x != ''])

решил так, подглядел вашу регулярку :D

→ Ссылка