2016-11-23 4 views
-1

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

Я собираюсь использовать плоды:

fruits = ['apple', 'orange', 'banana', 'papaya', 'kiwi'] 
baskets = [{'basket': 'one', 'fruit1': '', 'fruit2': ''}, 
      {'basket': 'two', 'fruit1': '', 'fruit2': ''}, 
      {'basket': 'three', 'fruit1': '', 'fruit2': ''}, 
      {'basket': 'four', 'fruit1': '', 'fruit2': ''}] 

Количество корзин не имеет значения.

Это, как я это делаю в данный момент:

import itertools 

def in_basket(frt, bskt): 
    if frt in bskt.values(): 
     return True 
    else: 
     return False 

g = itertools.cycle(fruits) 
fruit = next(g) 

for basket in baskets: 
    basket['fruit1'] = fruit 
     fruit = next(g) 

for basket in baskets: 
    while True: 
     if not in_basket(fruit, basket): 
      basket['fruit2'] = fruit 
      break 
     else: 
      fruit = next(g) 

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

Есть ли способ добиться равномерного распределения фруктов в каждом слоте корзины?

Редактировать - выход представляет собой обновленный список «корзин» с заполненными слотами фруктов.

+0

Каков требуемый результат (список образцов) для списков, которые вы упомянули? –

+1

Да, я знаю, что я ленив, но не могли бы вы привести пример того, как должен выглядеть ваш выход? –

+0

Результат - это просто обновленный список словарей «корзины». – rafello

ответ

1

Почему бы не использовать простой круговой:

g = itertools.cycle(fruits) 
for basket in baskets: 
    basket['fruit1'] = next(g) 
    basket['fruit2'] = next(g) 

Распределение является сбалансированным дизайн. Единственное предостережение в том, что, как только вы знаете, что такое fruit1 в одной корзине, fruit2 автоматически определяется. Если вам не нравится, вы можете использовать следующий фрукты для каждого из возможных фруктов:

g = itertools.cycle(fruits) 
fruit_iter = {} 
for i, fruit in enumerate(fruits): 
    fruit_iter[fruit] = itertools.cycle(fruits[i+1:] + fruits[:i]) 
for basket in baskets: 
    fruit = next(g) 
    basket['fruit1'] = fruit 
    basket['fruit2'] = next(fruit_iter[fruit]) 

Для первых корзин, каждый плод следует следующим в fruits порядке, но как только один будет повторно использовать в качестве fruit1 , следующий fruit2 будет следующим. Абсолютно нет случайных здесь, но распределение охватывает все возможные случаи с эквивалентом Вероятность (процент от числа случаев)

+0

Это на самом деле очень хорошо. Я предпочел бы, чтобы это «появилось» немного более случайным образом, но я думаю, что могу помыться этим, смешав порядок корзин в списке, а затем выпрямляю его снова, как только фрукты будут выделены. – rafello

+1

@rafello: см. Мое редактирование для * более приятного * распределения ... –

+0

Приятно, что при увеличении количества корзин есть хорошее и даже распределение фруктов по всем корзинам. Благодарю. – rafello

1

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

import numpy as np 

for basket in baskets: 
    for k in basket: 
     if k!='basket': 

      new_fruit = '' 

      while new_fruit in list(basket.values()): 
       new_fruit = np.random.choice(fruits) 

      basket[k] = new_fruit 
+0

Спасибо. Не имеет значения, в каком порядке заполняются плоские слоты. Проблема с этим кодом заключается в том, что слот fruit2 в корзинах два, три и четыре пустые. – rafello

+1

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

+1

@rafello Я обновил ответ, чтобы использовать случайную выборку. Таким образом, вам не нужно возиться со списком заказов. – Leo