-1

I've seen examples like this one on how to merge two lists into one dictionary, using the elements of one list as a key and the other, as the value. The only problem(better to say limitation) is that the size of the both lists need to be equal in order to achieve this.

Let's say I've got two lists like below:

A = ['SW1', 'SW2', 'SW3', 'SW4']
B = ['N1', 'N2', 'N3', 'N4', 'N5', 'N6', 'N7']

And the result I'm looking for must be a joint dictionary of these two lists in total random order, even the number of values per each key! (it may varies at each execution of the program).

e.g. at first run I get randomly something like this:

Run1 = {"SW1":["N1"], "SW2":["N2","N3"], "SW3":["N4"], "SW4":["N5", "N6", "N7"] }

and at the future runs it may/should show different orders/numbers/assignment of the second list elements as the values for each key taken from first list. How is this possible?

Community
  • 1
  • 1
Sina Sh
  • 1,177
  • 3
  • 15
  • 24
  • you can randomly partition B into `len(A)` partitions then create the dictionary from there. – jtitusj Oct 28 '16 at 04:43
  • 2
    It looks like you want us to write some code for you. While many users are willing to produce code for a coder in distress, they usually only help when the poster has already tried to solve the problem on their own. A good way to demonstrate this effort is to include the code you've written so far, example input (if there is any), the expected output, and the output you actually get (output, tracebacks, etc.). The more detail you provide, the more answers you are likely to receive. Check the [FAQ](http://stackoverflow.com/tour) and [How to Ask](http://stackoverflow.com/questions/how-to-ask). – TigerhawkT3 Oct 28 '16 at 04:44
  • @TigerhawkT3 No I'm not asking you to write me the code, but to enlighten me about the possible solutions like any existing python function which I may not be aware of, that's why I use a "How" there!! – Sina Sh Oct 28 '16 at 04:48
  • 1
    Well, first you would develop an algorithm, then implement it in Python, and finally, test it. This seems like a good challenge; there's no reason to deprive yourself of the fun of programming. – TigerhawkT3 Oct 28 '16 at 04:51

2 Answers2

1

Here is one approach you could take.

  1. Create a dictionary mapping each element of A to an empty list.

  2. For each element b of B, randomly choose an element of A and append b to the corresponding list in your dictionary. You can use random.choice() to make the random choices.

augurar
  • 12,081
  • 6
  • 50
  • 65
  • Your step 1 doesn't make sense to me, shouldn't you be creating a dictionary with the elements of A as the keys (not B) and empty lists as the values? Your step 2 has the possibility of assigning no elements to one or more of the keys in the dictionary -- OP doesn't discuss this option. – cdlane Oct 28 '16 at 18:33
  • @cdlane You're right about step 1, thanks for the correction. For step 2, this is true. If the OP wants each element of A to have at least one element of B then this would require modification. But when |B|>>|A| the probability of this happening becomes vanishingly small. – augurar Oct 28 '16 at 18:35
1

Here's an approach to randomize everything:

import random

A = ['SW1', 'SW2', 'SW3', 'SW4']
B = ['N1', 'N2', 'N3', 'N4', 'N5', 'N6', 'N7']

def randomize_to_dictionary(a, b):
    copy_a = a[:]
    copy_b = b[:]

    random.shuffle(copy_a)
    random.shuffle(copy_b)

    length_a = len(copy_a)
    length_b = len(copy_b)

    dictionary = {}

    start = 0

    for index, key in enumerate(copy_a):
        end = -1

        if index < length_a - 1:
            end = random.randint(start + 1, length_b - (length_a - index))

        dictionary[key] = copy_b[start:end]

        start = end

    return dictionary

print(randomize_to_dictionary(A, B))

The above assumes len(B) >= len(A). You should make that an explicit test if you use this code.

EXAMPLES

% python3 test.py
{'SW4': ['N7', 'N2', 'N3'], 'SW2': ['N5'], 'SW1': ['N1'], 'SW3': ['N4']}
% python3 test.py
{'SW3': ['N4', 'N5'], 'SW4': ['N1'], 'SW2': ['N3', 'N6'], 'SW1': ['N2']}
% python3 test.py
{'SW1': ['N4'], 'SW3': ['N3'], 'SW2': ['N7', 'N6', 'N5'], 'SW4': ['N2']}
%
cdlane
  • 40,441
  • 5
  • 32
  • 81
  • This is not very uniform. For a given element of B, the probability that it is assigned to a given element of A is not uniform. In particular, the first element of B will always be assigned to the first element of A. Additionally, the expected number of elements assigned to a given element of A is not constant. Even if you attempt to compensate for this by shuffling A and B, I don't think the distribution of lengths will be the same as a "balls and bins" distribution. – augurar Oct 28 '16 at 18:05
  • @augurar, the expected number of elements assigned to a given element of A is not constant by design (reread OP's description of the problem.) That the first element of B will always be assigned to the first element of A is intentional and discussed as well as is shuffling to change that choice. – cdlane Oct 28 '16 at 18:26
  • You misunderstand. The number of elements of B per element of A should be random for a given execution. But the [expected value](https://en.wikipedia.org/wiki/Expected_value) of the number of elements assigned should not depend on the position of the element in A. For example, if A has 3 elements and B has 5, then the first element of A has a 1/3 chance of being assigned 3 elements, while the last has only a 1/9 chance of the same. – augurar Oct 28 '16 at 18:37
  • @augurar, I've moved the optional shuffling of B into the (now) function and added shuffling of A. I did runs to check that the distribution of the lengths of the lists and their values is reasonably unbiased. – cdlane Oct 28 '16 at 19:03
  • I guess this rests on the OP's definition of "random". This algorithm tends to produce a "skewed" distribution of list lengths. For example, if B is large relative to A, then the probability that one list contains more than half of the elements of B approaches 1/2. – augurar Oct 28 '16 at 19:35