Не могу решить задачу (python)

Только начинаю изучать python, в курсе есть такая задача:

В кружке по борьбе занимаются 8 человек: Круглов Алексей, Ворожейкин Борик, Митин Сергей, Алешин Сергей, Кутиков Владимир, Круглов Денис, Бочкин Иван, Мечников Алексей. Выведите список учеников в алф. порядке. Подсчитайте, сколько в группе Сергеев, Алексеев и Денисов? Есть ли в группе однофамильцы?

Конкретно не понимаю как можно вывести кол-во Алексеев, Сергеев и Денисов. Пытался решить с помощью функции count, но не получилось(


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

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

Сперва вам надо выделить имена. Это можно сделать, разделив имя-фамилию по пробелу и сохранив только имя.

people = ["Круглов Алексей", "Ворожейкин Борик", "Митин Сергей", "Алешин Сергей", "Кутиков Владимир", "Круглов Денис", "Бочкин Иван", "Мечников Алексей"]

names = [fullname.split(" ")[1] for fullname in people]
print(names)

Output:

['Алексей', 'Борик', 'Сергей', 'Сергей', 'Владимир', 'Денис', 'Иван', 'Алексей']

Теперь в списке names надо искать Алексеев и т.д.

print(names.count("Алексей"))

Output:

2

Если список большой и/или надо посчитать много элементов, то лучше использовать словарь:

Построение ручками:

name_counts = {}
for name in names:
    if name not in name_counts:
        name_counts[name] = 1
    else:
        name_counts[name] += 1

print(name_counts)

Output:

{'Алексей': 2, 'Борик': 1, 'Сергей': 2, 'Владимир': 1, 'Денис': 1, 'Иван': 1}

С помощью Counter

import collections

name_counts = collections.Counter(names)
print(name_counts)

Output

Counter({'Алексей': 2, 'Сергей': 2, 'Борик': 1, 'Владимир': 1, 'Денис': 1, 'Иван': 1})
→ Ссылка
Автор решения: ppulseneon

Я не видел вашу программу, но могу предложить небольшой код, который поможет Вам решить данную задачу.

text = "Круглов Алексей"
counter = 0

if "Алексей" in text:
    counter=counter + 1

print (counter)
# Вывод: 1.

Или Вы можете использовать:

text = "Круглов Алексей"
counter = 0

if text.find("th"):
    counter = counter + 1

print (counter)
# Вывод: 1.

Используйте это для вашего массива (или в каком виде вы храните информацию)

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

Пример:

people = ['Круглов Алексей', 'Ворожейкин Борик', 'Митин Сергей', 'Алешин Сергей', 'Кутиков Владимир', 'Круглов Денис', 'Бочкин Иван', 'Мечников Алексей']
choices = ['Сергей', 'Алексей', 'Денис']

names = [full_name.split()[1] for full_name in people]
result = {name: names.count(name) for name in choices}

print(result)

stdout:

{'Сергей': 2, 'Алексей': 2, 'Денис': 1}
→ Ссылка
Автор решения: zaborschicov

Поскольку новичков много, считаю рациональным расписать задачу полностью.

Так понимаю в целом ввод может быть произвольным, так что сначала надо разобраться в том, как надо организовать ввод и "обработать" его перед началом работы:

raw_data = input() # получаем строку
split_data = raw_data.split(', ') # делаем из строки список и в качестве разделителя используем запятую с пробелом
firstname = [i.split(' ')[1] for i in split_data] # проходимся циклом for по разделённым данным, делим строку по пробелу и достаём только имя 
lastname = [i.split(' ')[0] for i in split_data] # тоже самое с фамилией

Сначала выведем имена в алфавитном порядке

split_data.sort() # сортируем данные
print(split_data) # выводим список
print(', '.join(split_data)) # список, переведённый в строку. Разделитель можно выбрать другой, просто заменив запятую с пробелом на что-то другое

Теперь перейдём к главной проблеме автора, подсчёт кол-ва определённых имён

print(firstname.count('Сергей'))
print(firstname.count('Алексей'))
print(firstname.count('Денис'))

Я предполагаю что ошибка была в том что вы пытались искать по списку, где все ФИ уже разделены. Дело тут в том, что в случае со списками функция count в случае со списками проверяет элементы списка на соответствие аргументу, который ей передали.

Решить же задачу с фамилиями можно с помощью преобразования типов данных

ln_set = set(lastname) #Создаём множество из списка фамилий. Одна из "фишек" этого типа данных – невозможность "засунуть" в него одинаковых элемента
if len(ln_set) == len(lastname): #в случае если есть одинаковые фамилии, множество будет короче списка
    print('Однофамильцев нет')
else:
    print('Однофамильцы есть')

Надеюсь смог максимально подробно расписать задачу. Удачи в изучении Python!

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

В целом все правильно делали. У строковых объектов есть метод count(), который при этом достаточно шустрый. Можно обойтись без разбиения на списки и т.д., натравливая его на целую строку, когда нужно просто посчитать простые вхождения без дальнейшей обработки:

names = 'Круглов Алексей, Ворожейкин Борик, Митин Сергей, Алешин Сергей, Кутиков Владимир, Круглов Денис, Бочкин Иван, Мечников Алексей'
search = ['Алексей', 'Сергей', 'Денис']

for s in search:
    counts = names.count(s)
    print(f'{s}: {counts}')

Можно сделать чуть сложнее через регулярные выражения. Тогда исключим случаи наложения имени на фамилию или другого вхождения, определяя шаблон для целого слова.

import re
names = 'Круглов Алексей, Ворожейкин Борик, Митин Сергей, Алешин Сергей, Кутиков Владимир, Круглов Денис, Бочкин Иван, Мечников Алексей'
search = ['Алексей', 'Сергей', 'Денис']

counts = dict().fromkeys(search, 0)
for e in re.findall('({})'.format('|'.join('\\b{}\\b'.format(s) for s in search)), names, re.IGNORECASE):
    counts[e] += 1

print(counts)
→ Ссылка