Как найти частоту значений в списке списков и объединить с другим существующим списком по общему значению? - PullRequest
0 голосов
/ 19 июня 2020

У меня есть вложенный список c исполнителей музыки, состоящий из пользовательского ввода, скажем:

artists_list = [['A', 'B', 'C'],
                ['A', 'C', 'B'],
                ['B', 'A', 'D']]

Мне также удалось создать отдельный список, основанный на порядке ввода (не по алфавиту ), который присваивает жанр каждому уникальному исполнителю в приведенном выше списке:

artist_genre_list = [['A', 'Rock'],
                     ['B', 'Rap'],
                     ['C', 'Rock'],
                     ['D', 'Blues']]

Как мне объединить эти два, чтобы сделать либо основной список, либо словарь, включая счетчик частот, подобный:

master_list = [['A', 'Rock', 3],
               ['B', 'Rap', 3],
               ['C', 'Rock', 2],
               ['D', 'Blues', 1]]

master_dict = {'A': {
                  'Genre': 'Rock',
                  'Frequency': 3},
               'B': {
                  'Genre': 'Rap',
                  'Frequency': 3},
               'C': {
                  'Genre': 'Rock',
                  'Frequency': 2},
               'D': {
                  'Genre': 'Blues',
                  'Frequency': 1}
               }

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

# Counters
count = 1
new_artist_counter = 0

# Generate Lists
artists_input_list = []
aux_artists_list = []
aux_genre_list = []
aux_artists_genre_list = []

def merge(aux_artists_list, aux_genre_list):
    merged_list = [[aux_artists_list[i], aux_genre_list[i]] for i in range(0, 
                    len(aux_artists_list))]
    return merged_list

while count < 4:

    # Inputs
    a1_in = str(input("Artist 1: "))
    a2_in = str(input("Artist 2: "))
    a3_in = str(input("Artist 3: "))

    artists_input_list.append([a1_in, a2_in, a3_in])

    # Determines if new unique artist has been added and asks for it's genre
    while new_artist_counter < len(artists_input_list):

        for entry in artists_input_list:

             for artist in entry:

                 if artist not in aux_artists_list:
                     aux_artists_list.append(artist)
                     genre_input = input("What is "+artist+"'s genre? ")
                     aux_genre_list.append(genre_input)
                 else: continue

        new_artist_counter += 1  

    aux_artists_genre_list = merge(aux_artists_list, aux_genre_list)

    # Counter updates
    count += 1

print(artists_input_list)
print(aux_artists_genre_list)

1 Ответ

1 голос
/ 20 июня 2020

Это то, что я придумал. Сначала он сглаживает ваш список исполнителей, получает частоту каждого элемента в списке, а затем объединяет его с вашим genre списком

from itertools import groupby, chain
import pprint

artists_list = [
  ['A', 'B', 'C'],
  ['A', 'C', 'B'],
  ['B', 'A', 'D']
]

artist_genre_list = [
  ['A', 'Rock'],
  ['B', 'Rap'],
  ['C', 'Rock'],
  ['D', 'Blues']
]

frequencies = {
  key: len(list(value)) for key,
  value in groupby(sorted(chain.from_iterable(artists_list)))
}

frequency = [{
    letter: {
      'Genre': genre,
      'Frequency': next((freq
        for key, freq in frequencies.items() if key is letter), 0)
    }
  }
  for letter, genre in artist_genre_list
]

pprint.pprint(frequency)

Я использовал pprint просто для вывода tidier, который отображается как

[{'A': {'Frequency': 3, 'Genre': 'Rock'}},
 {'B': {'Frequency': 3, 'Genre': 'Rap'}},
 {'C': {'Frequency': 2, 'Genre': 'Rock'}},
 {'D': {'Frequency': 1, 'Genre': 'Blues'}}]
...