Extracting keys-values from dictionary - python

import random
dictionary = {'dog': 1,'cat': 2,'animal': 3,'horse': 4}
keys = random.shuffle(list(dictionary.keys())*3)
values = list(dictionary.values())*3
random_key = []
random_key_value = []
random_key.append(keys.pop())
random_key_value.append(???)
For random_key_values.append, I need to add the value that corresponds to the key that was popped. How can I achieve this? I need to make use of multiples of the list and I can't multiply a dictionary directly, either.

I'm going on python (you should specify the language in your question).
If I understand, you want to multiply the elements in the dictionary. So
list(dictionary.keys()) * 3
is not your solution: [1,2] * 3 results in [1,2,1,2,1,2]
Try instead list comprehension:
[i * 3 for i in dictionary.keys()]
To take into account the order (because you shuffle it) shuffle the keys before the multiplication, then create the values list (in the same order that the shuffled keys) and finally multiply the keys:
keys = dictionary.keys()
random.shuffle(keys)
values = [dictionary[i]*3 for i in keys]
keys = [i * 3 for i in keys]
And finally:
random_key.append(keys.pop())
random_key_value.append(values.pop())
Also take care about the random function, it doesn't work as you are using it. See the documentation.

Related

the difference between list and dictionary in python

code A :
t1 = {}
t1[0] = -5
t1[1] = 10.5
code B :
t2 = []
t2[0] = -5
t2[1] = 10.5
why code B has "IndexError: list assignment index out of range" and how to solve it?
Dictionaries are hashsets. They pair arbitrary (hashable) keys with values, and there is no expectation that those keys are consecutive, or even in fact numbers
replacement_dict = {'old_name': 'new_name'} # you could use this to implement a find/replace
By comparison, lists are densely-packed and their indices (not keys -- this is a different term accessed the same way with the object[index] notation) are numbers. Because of this, you can't just access a random value that's greater than the length of the list, you must use append instead.
lst = []
lst[0] = 'blah' # throws an IndexError because len(lst) is 0
lst.append('blah')
assert lst[0] == 'blah
Dictionaries work like key-value pairs. Every time you assign a new value in a dictionary, you create a new key-value pair.
A list is like an array that you can extend at will, but if you try to access an index that is over its current size, it will return an error. You typically extend a list by using t2.append(value).
A dictionary allows assignment of elements that don't exist yet. Lists don't. That's just the way they're designed.
You can fix this two ways. First is to initialize the list to the size it needs to be:
t2 = [None]*2
The second is to call append instead of using =:
t2 = []
t2.append(-5)
t2.append(10.5)
A dictionary stores data with name values.
dictionary = {"name": "value"}
print(dictionary["name"])
# Prints "value".
A list stores a sequence of values. There aren't any names for the values, they are accessed via an index.
list = ["value", "other value"]
print(list[0])
# Prints "value".
To fix your problem use append.
t2 = []
t2.append(-5)
t2.append(10.5)

Combinations of elements at various keys of a dict

I have a python dict which has various keys such that dict.keys()=[1,2,3] and each key holds an array of possibly different size such that dict[1] = [1,3,6], dict[2] = ['a', 'b'] dict[3] = [x]. I want to have a new array where I get all possible combinations of the n elements from each of the arrays.
For example, if the arrays were provided beforehand,
arr_1 = itertools.combinations(dict[1],n)
arr_2 = itertools.combinations(dict[2],n)
arr_3 = itertools.combinations(dict[3],n)
and then finally,
final = itertools.product(arr_1, arr_2, arr_3)
In a scenario where I do not the keys of the dict and the array sizes, how can I create the final array ?
If I understand correctly
itertools.product(*[itertools.combinations(v, min(n, len(v)) for v in dic.values()])
should do the trick.
edit: adjusted w.r.t. comments.
Your question is a bit coarsely stated. If you are asking, how you can dynamically form the final array when you need to determine dict keys and values on the fly, you could do it like this:
def combo_dist(dict): # <--- dict is your starting dictionary
array = []
for v in dict.values(): # <--- all values from your dict
arrays.append(itertools.combination(v,len(v)))
# now array should be populated and you can make your final product:
final = itertools.product(*array)
return final
# now call this function:
final_array = combo_dict(your_dict)
now, if I understood correctly, this is the spelled out version of the algorithm. You could actually do a one-liner with list comprehension:
final_array = itertools.product(*[itertools.combinations(v, len(v)) for v in your_dict.values()])
but mind, that here the order of values is not deterministic. You may want to use sorted() as well in one of the steps. Depends on your needs.

Generating random numbers as the value of dictionary in python

Could you please tell me how can I generate a dictionary with 100 rows that have random number between 0 and 1 in each row as the value? For example in data frame, I can have:
df['Rand'] = random.sample(random.random(), 100)
But I don't know how to do that for a dictionary.
I think what you want is something like:
{k: random.random() for k in range(100)}
Firstly, it should be list and not dict. Check: In Python, when to use a Dictionary, List or Set?
In order to get the list of values, you may use list comprehension as:
>>> import random
>>> row_count = 10
>>> my_list = [random.random() for i in range(row_count)]
# Value of 'my_list':
# [0.9158936600374181, 0.8998648755500501, 0.07002867165493243, 0.6694284854833131, 0.4903966580363698, 0.9462143737260301, 0.8014661448602305, 0.47964245438139297, 0.42326131297319725, 0.77540761767324]
In order to fetch 5th item (i.e. 4th index):
>>> my_list[4]
0.4903966580363698

Copying first n items of a dictionary into another dictionary

This is a simple question but I am unable to code this in python. I want to copy first n items ( supposedly 100 ) i.e both the values and keys into another empty dictionary. I'll give a more clear picture of this. I created a dictionary and sorted it using OrderedDict. My code for sorting it is :
ordP = OrderedDict(reversed(sorted(wcP.items(), key=lambda t: t[1])))
Here ordP is the ordered dictionary I got. This is in descending order. And my original dictionary is wcP. I want to put the first 100 values of ordP i.e the first 100 maximum values of ordP ( sorted according to the keys ) in a new dictionary.
Dictionaries aren't ordered, but if you just want a random selection:
new_values = dict(your_values.items()[:n])
Or, for those obsessed with laziness:
import itertools
new_values = dict(itertools.islice(your_values.iteritems(), n))
If there's a particular sort you want to impose, define a key function that takes the key and value. People usually do lambdas, but there's no reason you can't use a full function.
def example_key_func((key, value)):
return key * value
new_dict = dict(sorted(your_values.items(), key=example_key_func)[:n])
n = 100
assert len(d.keys()) >= n
dic100 = {k:v for k,v in list(d.items())[:n]}

Correspendence between list indices originated from dictionary

I wrote the below code working with dictionary and list:
d = computeRanks() # dictionary of id : interestRank pairs
lst = list(d) # tuples (id, interestRank)
interestingIds = []
for i in range(20): # choice randomly 20 highly ranked ids
choice = randomWeightedChoice(d.values()) # returns random index from list
interestingIds.append(lst[choice][0])
There seems to be possible error because I'm not sure if there is a correspondence between indices in lst and d.values().
Do you know how to write this better?
One of the policies of dict is that the results of dict.keys() and dict.values() will correspond so long as the contents of the dictionary are not modified.
As #Ignacio says, the index choice does correspond to the intended element of lst, so your code's logic is correct. But your code should be much simpler: d already contains IDs for the elements, so rewrite randomWeightedChoice to take a dictionary and return an ID.
Perhaps it will help you to know that you can iterate over a dictionary's key-value pairs with d.items():
for k, v in d.items():
etc.

Categories

Resources