Распечатка повторяющихся элементов из вложенного списка

#python #list #function #nested-lists #python-3.9

#python #Список #функция #вложенные списки #python-3.9

Вопрос:

Система просит пользователя ввести имя сладости. Если этот sweet не существует в списке, он должен сообщить об этом пользователю. Если это сладкое есть в списке, список распечатывает все детали списка каждый раз, когда это конкретное сладкое упоминается в списке. Например, если я введу Cadbury:

 # List of transactions [[customer, sweet, amount, money, day, month]
lst_sweets = [
    ["Tom", "Cadbury", 2, 9, 1, 10],
    ["Rachel", "Galaxy", 5, 10, 1, 9],
    ["Rachel", "Smarties", 4, 10, 1, 8],
    ["Lisa", "Gum drops", 10, 9, 1, 7],
    ["Donald", "Cadbury", 1, 5, 1, 6],
    ["Marie", "Smarties", 5, 10, 1, 5]
]
def sweet_purchases():
    x = input("Enter the sweet name")

    p = -1
    sum = 0

    for i in range(len(lst_sweets)):

        item = lst_sweets[i]
        name = item[1]

        if name == x:
            p = i

    if p == -1:
        print("customer not in list")
    else:

        sweetx = lst_sweets[p]
        print("Name:", sweetx[0], "Sweet:", sweetx[1], "amount:", sweetx[2], "money:", sweetx[3], "day:", sweetx[4], "month:", sweetx[5])

 

желаемый результат:
Имя:, Том, Сладкий:, Кэдбери, сумма:, 2, деньги:, 9, день:, 1, месяц:, 10
Имя:, Дональд, Сладкий :, Кэдбери, сумма:, 1, деньги:, 5, день:, 1, месяц:, 6

фактический результат: Имя:, Том, Сладкий:, Кэдбери, сумма:, 2, деньги:, 9, день:, 1, месяц:, 10

Кто-нибудь знает, почему он не выводит оба? Спасибо

Ответ №1:

Если вы обнаружите несколько совпадений, вы перезаписываете p , оставляя вам только одно совпадение. Вы должны печатать в цикле:

 lst_sweets = [
    ["Tom", "Cadbury", 2, 9, 1, 10],
    ["Rachel", "Galaxy", 5, 10, 1, 9],
    ["Rachel", "Smarties", 4, 10, 1, 8],
    ["Lisa", "Gum drops", 10, 9, 1, 7],
    ["Donald", "Cadbury", 1, 5, 1, 6],
    ["Marie", "Smarties", 5, 10, 1, 5]
]

fields = ["name", "sweet", "amount", "money", "day", "month"]

x = input("Enter the sweet name: ")
found = False
for sweet in lst_sweets:
    if sweet[1] == x:
        found = True
        print(", ".join(f"{field}: {val}" for field, val in zip(fields, sweet)))
if not found:
    print("sweet not found")
 

Ответ №2:

 # List of transactions [[customer, sweet, amount, money, day, month]
lst_sweets = [
    ["Tom", "Cadbury", 2, 9, 1, 10],
    ["Rachel", "Galaxy", 5, 10, 1, 9],
    ["Rachel", "Smarties", 4, 10, 1, 8],
    ["Lisa", "Gum drops", 10, 9, 1, 7],
    ["Donald", "Cadbury", 1, 5, 1, 6],
    ["Marie", "Smarties", 5, 10, 1, 5]
]
def sweet_purchases():
    x = input("Enter the sweet name")

    p = [] # make a list that stores the matching index
    sum = 0

    for i in range(len(lst_sweets)):

        item = lst_sweets[i]
        name = item[1]

        if name == x:
            p.append(i)

    if p == None: # if the list is empty
        print("customer not in list")
    else:
        # Now iterate over the correct list of index and print the values
        for i in p:
            sweetx = lst_sweets[i]
            print("Name:", sweetx[0], "Sweet:", sweetx[1], "amount:", sweetx[2], "money:", sweetx[3], "day:", sweetx[4], "month:", sweetx[5])
 

Ответ №3:

Способ, которым вы настраиваете p каждый цикл, очищает предыдущее совпадение.

 def sweet_purchases():
  x = input("Enter the sweet name")
  cnt=0
  for entry in lst_sweets:
    if entry[1] == x:
      print(entry) # or whatever
      cmt =1
  if not cmt:
    print('No joy')
 

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

 def sweet_purchases():
  x = input("Enter the sweet name")
  hits=[]
  for entry in lst_sweets:
    if entry[1] == x:
      hits.append(entry)
   return hits
 

Но «питонический» способ просто найти список без их обработки — использовать понимание:

 def sweet_purchases():
  x = input("Enter the sweet name")
  return [e for e in lst_sweets
            if e[1] == x]
 

Ответ №4:

Ваш цикл приводит только к одному совпадению. Более точный (и простой!) способ сделать это — использовать понимание списка для создания отфильтрованной версии исходного списка, а затем выполнить итерацию по отфильтрованному списку:

 def sweet_purchases():
    sweet = input("Enter the sweet name")
    filtered_entries = [entry for entry in lst_sweets if entry[1] == sweet]
    if not filtered_entries:
        print("customer not in list")
        return
    for entry in filtered_entries:
        [name, sweet, amount, money, day, month] = entry
        print(f"Name: {name} Sweet: {sweet} amount: {amount} money: {money} day: {day} month: {month}")