Учитывая один элемент кортежа, верните другой

#python

#python

Вопрос:

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

 'b.name("drummer") = "Nick"'

class Band:

    def __init__(self):
        self.band = [
            ("Nick", "drummer"),
            ("Dave", "singer"),
            ("Gary", "bass"),
            ("Bill", "guitar")
            ]

    def name(self):
        names = []
        for role in self.band:
            names.append(role[0])
            return names

b = Band()
b.name()
 

Комментарии:

1. Во-первых, было бы намного проще, если self.band бы было a dict . Затем вам понадобится метод get_name , который принимает роль в качестве аргумента. Наконец, просто найдите роль в dict и верните значение. Предложение : проведите небольшое исследование dict.get() функции.

2. Проблема в том, что «возврат» имеет слишком большой отступ, так что он возвращает «имена» в конце первой итерации.

3. У вас проблема с отступом, return должна быть на том же уровне, что и for

4. Даже исправляя отступ, name возвращает имена всех участников группы, а не имя участника группы с заданной ролью.

Ответ №1:

Похоже, вы пытаетесь реализовать список ассоциаций: https://en.wikipedia.org/wiki/Association_list

 def get_name(self, role):
    # tuple destructuring is useful here
    for (current_name, current_role) in self.band:
        if current_role == role:
            return current_name
    
    # role was not found
    return None
 

Ответ №2:

Давайте немного разберем эту проблему:

1. Каковы входные данные для вашей name функции? Каковы выходные данные вашей name функции?

Прямо сейчас ваш def name(self) ввод не требуется. Вместо этого нам нужно ввести некоторые входные данные (имя роли) для вычисления результата. Мы также, вероятно, хотим спросить, могут ли несколько человек иметь одну и ту же роль, поэтому мы можем захотеть вернуть список вместо одного значения:

 def name(self, role : str) -> List[str]:
 

2. Как нам найти всех людей с заданной ролью?

Что ж, мы можем просмотреть все заданные назначения ролей и проверить, соответствует ли роль той, которую мы ищем. Что-то вроде этого:

 def name(self, role : str) -> List[str]:
   result = []
   for assignment in self.band:
     if assignment[1] == role:
       result.append(assignment[0])
   return result
 

Приведенное выше решение функционально, но немного многословно. Когда вы станете более опытным программистом, вы поймете, что это довольно распространенный шаблон, который мы можем решить с помощью так называемого понимания списка. Это просто сокращение для того, что мы написали выше:

 def name(self, role : str) -> List[str]:
   return [p[0] for p in self.band if p[1] == role]
 

ПРИМЕЧАНИЕ: использование типов / интерфейсов

По мере изучения программирования я рекомендую вам подумать и отметить различные типы и интерфейсы, используемые в ваших программах. Это поможет вам разобраться в вашем коде. Например, вы можете представить эту проблему следующим образом:

 from typing import List, Tuple

BandListT = List[Tuple[str, str]]

class Band:
  members : BandListT
  def __init__(self, members : BandListT) -> None:
      self.members = members

  def get_names_by_role(self, role : str) -> List[str]:
      names = []
      for member in self.members:
        if member[1] == role:
            names.append(member[0])
      return names

BAND_MEMBERS : BandListT = [
    ("Nick", "drummer"),
    ("Dave", "singer"),
    ("Gary", "bass"),
    ("Bill", "guitar")
    ]        
b = Band(BAND_MEMBERS)
print(b.get_names_by_role("drummer"))
 

Вы заметите несколько изменений в вашем частичном решении:

  • Я передаю членов группы в качестве параметра конструктору. Это потому, что мы можем захотеть иметь разные группы с разными участниками.
  • Я определил BandListT как псевдоним типа, поэтому мы можем использовать его во всем нашем коде
  • Я переименовал name в get_names_by_role , чтобы немного прояснить функцию этого метода.
  • Я добавил аннотации типов ( str , Tuple , List ), чтобы другим разработчикам и программе проверки типов было ясно, что представляет каждая переменная.

Эти навыки сослужат вам хорошую службу, когда вы продолжите свой путь разработчика! Приветствия!

Repl: https://replit.com/@DerekTBrown/ScratchyJadedFilename#main.py