Setting random values to half of the dictionary and copying the rest

Viewed 99

I have a python dictionary created by an other list via:

a = dict.fromkeys(some_list)

Because I created this dictionary via the above command all my values in the dictionary are None as expected. And it looks like this:

a = {('A', 'B'): None,
     ('A', 'C'): None,
     ('B', 'A'): None,
     ('C', 'A'): None}

What I want is: to be able to change the None values to random numbers via random.uniform(0,1).

However I don't wanna do this to whole of the dictionary instead only the first 2 keys (('A', 'B'), ('A', 'C')), and the rest (('B', 'A'), ('C', 'A')) should be copied from the first 2 keys.

Following sets all the values to random numbers. However I could not find a way to set the first two as random and the rest copied without hardcoding the keys.

for key in a:
    a[key] = random.uniform(0, 1)

Any Suggestions?

3 Answers
visited = set()

for key in a:

  if key in visited:
    continue
  
  # mark key as visited
  visited.add(key)
  visited.add(key[::-1])

  value = np.random.uniform(0, 1)

  a[key] = value
  a[key[::-1]] = value

More dynamic and efficient solution is to hash the given key such that the tuple-order is being ignored

def hash_tuple(t):

  hash_value = 0

  for elem in t:
    
    if isinstance(elem, int):
      
      hash_value += elem
    
    elif isinstance(elem, str):

      hash_value += ord(elem)
    
    else:

      raise ValueError(f'Invalid Type {type(elem)}')
  
  return hash_value

global_seed = np.random.randint(0, 100)

for key in a:

  seed = hash_tuple(key) + global_seed
  random = np.random.RandomState(seed)

  value = random.uniform(0, 1)

  a[key] = value

Assuming the keys in your dict weren't inserted in any particular order:

for key in a:
    n = random.uniform(0, 1)
    a[key] = n
    if (key[1], key[0]) in a:
        a[key[1], key[0]] = n

My method allows not only two elements in the key tuple, can be any number and the order also doesn't matter.

import random

a = {('A', 'B'): None,
     ('A', 'C'): None,
     ('B', 'A'): None,
     ('C', 'A'): None}

tuple_group_dict = {t: ''.join(sorted(t)) for t in a.keys()}
# print(tuple_group_dict)
group_rand_dict = {g: random.uniform(0, 1) for g in tuple_group_dict.values()}
# print(group_rand_dict)
for k in a:
    a[k] = group_rand_dict[tuple_group_dict[k]]
print(a)

# {('A', 'B'): 0.19127468345979626, ('A', 'C'): 0.5162477118368421, ('B', 'A'): 0.19127468345979626, ('C', 'A'): 0.5162477118368421}
Related