Создание словаря не всегда работает

#python #dictionary #for-loop #random

Вопрос:

Я пытаюсь автоматически сгенерировать словарь с помощью цикла for (я

Например, я хочу создать 10 пользователей(обычно), иногда создается 7, 8 или 9, но редко 10.

Код ниже.

 import random  class practica6:  #Create our constructor  def __init__(self) -gt; None:  # Initialize users dictionary  self.usuarios = {}  #List of possible names the users can take  self.nombres = ['Mario', 'Pepe', 'Angel', 'Joaquin', 'Jesus', 'Edson', 'Emilio',   'Eli', 'Francisco', 'Sergio',   'Erick', 'David', 'Liam', 'Noah', 'Oliver', 'William', 'James', 'Benjamin', 'Lucas',   'Henry', 'Alexander',   'Mason', 'Michael', 'Ethan', 'Mateo', 'Sebastian', 'Jack', 'Peter', 'Josh',   'Patricia', 'Luis', 'Gerardo', 'Carmen']    def generar_diccionario_usuarios(self, numero_usuarios : int):  #Generate a dictionary with random names (keys) and random priority (values) keys :   #values  for i in range(numero_usuarios):  self.usuarios[random.choice(self.nombres)] = random.randint(1, 10)  #DEBUG : Print our users dictionary  print(self.usuarios)  #Test app practica = practica6() n = 10 print('Usuarios:') practica.generar_diccionario_usuarios(n)  

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

1. Вы хотите сказать, что беспокоитесь о том, что он недостаточно часто генерирует целое значение 10? Это только что произошло со мной, дважды '{Alexander': 3, 'Jack': 1, 'Erick': 10, 'David': 10, 'Carmen': 7} . Именно так работают случайные числа…

2. Я немного не совсем понимаю. Вы говорите: «Я хочу создать 10 пользователей(обычно)», но ваш цикл управляется numero_usuarios тем, что вы установили значение 5, разве это не всегда создает 5 пользователей? (На самом деле это может дать меньше, если random.choice дважды выбрать имя, которое перезапишет предыдущее значение, это та проблема, о которой вы говорите?)

3. Нет, я говорю, что это не создает 10 пользователей или число, которое я хочу. Если я использую небольшое число «n», например 5, оно создает пять пользователей, но если я хочу увеличить его до gt;10, это просто не работает вообще.

Ответ №1:

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

 for nombre in random.sample(self.nombres, numero_usuarios):  self.usuarios[nombre] = random.randint(1, 10)  

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

1. Действительно!, спасибо вам за ваш ответ. Я думаю, что это более простое решение.

Ответ №2:

Это потому, что вы получаете дубликаты ключей в своем диктанте при случайном выборе одного за раз.

Вы можете создать список numero_usarios отдельных ключей с помощью

 distinct_names = random.sample(self.nombres, k=numero_usarios)  

и список случайных целых чисел с

 values = random.choices(range(1, 11), k=numero_usarios)  

Затем вы можете создать диктант, связав эти списки с

 self.usuarios = dict(zip(distinct_names, values))  

Ответ №3:

проблема в том, что иногда «random.choice(self.nombres)» генерирует одно и то же имя, поэтому оно перевешивается, поэтому решением является :

 import random class practica6:  #Create our constructor  def __init__(self) -gt; None:  # Initialize users dictionary  self.usuarios = {}  #List of possible names the users can take  self.nombres = ['Mario', 'Pepe', 'Angel', 'Joaquin', 'Jesus', 'Edson', 'Emilio',   'Eli', 'Francisco', 'Sergio',   'Erick', 'David', 'Liam', 'Noah', 'Oliver', 'William', 'James', 'Benjamin', 'Lucas',   'Henry', 'Alexander',   'Mason', 'Michael', 'Ethan', 'Mateo', 'Sebastian', 'Jack', 'Peter', 'Josh',   'Patricia', 'Luis', 'Gerardo', 'Carmen']    def generar_diccionario_usuarios(self, numero_usuarios : int):  #Generate a dictionary with random names (keys) and random priority (values) keys :   #values  for i in range(numero_usuarios):  name = random.choice(self.nombres)  while name in self.usuarios.keys():  name = random.choice(self.nombres)  self.usuarios[name] = random.randint(1, 10)  #DEBUG : Print our users dictionary  print(self.usuarios)  #Test app practica = practica6() n = 10 print('Usuarios:') practica.generar_diccionario_usuarios(n)  

спасибо, надеюсь, это сработает, потому что это сработало для меня!

Ответ №4:

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

 import random  class Practica6:   def __init__(self) -gt; object:  # Initialize users dictionary  self.usuarios = {}  #List of possible names the users can take- shuffled  self.nombres = random.shuffle(['Mario', 'Pepe', 'Angel', 'Joaquin', 'Jesus', 'Edson', 'Emilio',   'Eli', 'Francisco', 'Sergio',   'Erick', 'David', 'Liam', 'Noah', 'Oliver', 'William', 'James', 'Benjamin', 'Lucas',   'Henry', 'Alexander',   'Mason', 'Michael', 'Ethan', 'Mateo', 'Sebastian', 'Jack', 'Peter', 'Josh',   'Patricia', 'Luis', 'Gerardo', 'Carmen'])    def generar_diccionario_usuarios(self, numero_usuarios : int):  #Generate a dictionary with random names (keys) and random priority (values) keys :   #values  for i in range(numero_usuarios):  chosen = self.nombres.pop() # random.choice(self.nombres)  self.usuarios[chosen] = random.randint(1, 10)  #DEBUG : Print our users dictionary  print(self.usuarios)    #Test app practica = Practica6() n = 5 print('Usuarios:') practica.generar_diccionario_usuarios(n)  

Инициализация всегда возвращает экземпляр класса. Я думаю, что этот приведенный выше код может достичь того, что вы ищете? В качестве альтернативы было бы неплохо создать функцию «фабрика» для создания множества экземпляров объекта с различными свойствами, а не использовать его в качестве метода. Просто одна мысль.

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

1. Да, это еще одно хорошее решение! Я совсем забыл об идее удалить это имя из списка. Спасибо

2. @MarioAlmaguer спасибо. Использование pop в рандомизированном списке было самым простым способом, который я мог себе представить. Я думал, что я был первым ответом, а потом, когда я опубликовал, я был третьим или что-то в этом роде 😀 Я не самый быстрый наборщик!