tekknolagi
tekknolagi

Reputation: 11012

How can I get a random key-value pair from a dictionary?

In Python, given a dictionary like

{
    'VENEZUELA': 'CARACAS',
    'CANADA': 'OTTAWA'
}

How can I choose a random item (key-value pair)?

What if I only need the key, or only the value - can it be optimized?

Upvotes: 231

Views: 491513

Answers (19)

patriciasz
patriciasz

Reputation: 1405

(this comes with a number of caveats, the main one being that this isn't actually random...see the comments for details)

If you don't want to use the random module, you can also try popitem():

>> d = {'a': 1, 'b': 5, 'c': 7}
>>> d.popitem()
('a', 1)
>>> d
{'c': 7, 'b': 5}
>>> d.popitem()
('c', 7)

Since the dict doesn't preserve order, by using popitem you get items in an arbitrary (but not strictly random) order from it.

Also keep in mind that popitem removes the key-value pair from dictionary, as stated in the docs.

popitem() is useful to destructively iterate over a dictionary

Upvotes: 14

SHERMUKHAMMAD TEMIROV
SHERMUKHAMMAD TEMIROV

Reputation: 26

Her is my sample answer

import random

data = {f"key{n}" : n for n in range(100)}
print(random.choice(list(data.values())))

Upvotes: 1

lavee_singh
lavee_singh

Reputation: 1449

Give a dictionary a, use:

import random
random_key = random.sample(a.keys(), 1)[0]

Upvotes: 16

Israel Z. DelaMora
Israel Z. DelaMora

Reputation: 27

In Python 3.x, the objects returned by methods dict.keys(), dict.values() and dict.items() are view objects, which cannot be used directly with random.choice.

One option is to pass random.choice a list comprehension that extracts the candidate values to choose from:

import random

colors = {
    'purple': '#7A4198',
    'turquoise': '#9ACBC9',
    'orange': '#EF5C35',
    'blue': '#19457D',
    'green': '#5AF9B5',
    'red': ' #E04160',
    'yellow': '#F9F985'
}

color = random.choice([color_value for color_value in colors.values()]

print(f'The new color is: {color}')

Upvotes: 0

Romero Morais
Romero Morais

Reputation: 131

Here are separate functions to get a key, value or item:

import random

def pick_random_key_from_dict(d: dict):
    """Grab a random key from a dictionary."""
    keys = list(d.keys())
    random_key = random.choice(keys)
    return random_key

def pick_random_item_from_dict(d: dict):
    """Grab a random item from a dictionary."""
    random_key = pick_random_key_from_dict(d)
    random_item = random_key, d[random_key]
    return random_item

def pick_random_value_from_dict(d: dict):
    """Grab a random value from a dictionary."""
    _, random_value = pick_random_item_from_dict(d)
    return random_value

These can be used like:

d = {...}
random_item = pick_random_item_from_dict(d)

These approaches only copy the keys of the dict, mitigating the need to copy the data in order to use random.choice. Once we have the key, we can get the corresponding value, and thus an item.

Upvotes: 3

user225312
user225312

Reputation: 131647

Call random.choice on the keys of the dictionary (the countries).

In 2.x, the keys can be chosen from directly:

>>> import random
>>> d = dict(Venezuela = 1, Spain = 2, USA = 3, Italy = 4)
>>> random.choice(d.keys())
'Venezuela'
>>> random.choice(d.keys())
'USA'

In 3.x, create a list first, e.g. random.choice(list(d.keys())).

Upvotes: 17

srattigan
srattigan

Reputation: 664

To get a random key, use random.choice(), passing the dictionary keys like so:

import random
keys = list(my_dict)
country = random.choice(keys)

Upvotes: 3

Gerrat
Gerrat

Reputation: 29690

Make a list of the dictionary's items, and choose randomly from that in the usual way:

import random
d = {'VENEZUELA':'CARACAS', 'CANADA':'OTTAWA'}
country, capital = random.choice(list(d.items()))

Similarly, if only a value is needed, choose directly from the values:

capital = random.choice(list(d.values()))

Upvotes: 393

campkeith
campkeith

Reputation: 672

I needed to iterate through ranges of keys in a dict without sorting it each time and found the Sorted Containers library. I discovered that this library enables random access to dictionary items by index which solves this problem intuitively and without iterating through the entire dict each time:

>>> import sortedcontainers
>>> import random
>>> d = sortedcontainers.SortedDict({1: 'a', 2: 'b', 3: 'c'})
>>> random.choice(d.items())
(1, 'a')
>>> random.sample(d.keys(), k=2)
[1, 3]

Upvotes: 0

Aditya Raj
Aditya Raj

Reputation: 29

To select 50 random key values from a dictionary set dict_data:

sample = random.sample(set(dict_data.keys()), 50)

Upvotes: 0

Mike Gashler
Mike Gashler

Reputation: 669

Here is a little Python code for a dictionary class that can return random keys in O(1) time. (I included MyPy types in this code for readability):

from typing import TypeVar, Generic, Dict, List
import random

K = TypeVar('K')
V = TypeVar('V')
class IndexableDict(Generic[K, V]):
    def __init__(self) -> None:
        self.keys: List[K] = []
        self.vals: List[V] = []
        self.dict: Dict[K, int] = {}

    def __getitem__(self, key: K) -> V:
        return self.vals[self.dict[key]]

    def __setitem__(self, key: K, val: V) -> None:
        if key in self.dict:
            index = self.dict[key]
            self.vals[index] = val
        else:
            self.dict[key] = len(self.keys)
            self.keys.append(key)
            self.vals.append(val)

    def __contains__(self, key: K) -> bool:
        return key in self.dict

    def __len__(self) -> int:
        return len(self.keys)

    def random_key(self) -> K:
        return self.keys[random.randrange(len(self.keys))]

Upvotes: -3

Cadoiz
Cadoiz

Reputation: 1676

I found this post by looking for a rather comparable solution. For picking multiple elements out of a dict, this can be used:

idx_picks = np.random.choice(len(d), num_of_picks, replace=False) #(Don't pick the same element twice)
result = dict ()
c_keys = [d.keys()] #not so efficient - unfortunately .keys() returns a non-indexable object because dicts are unordered
for i in idx_picks:
    result[c_keys[i]] = d[i]

Upvotes: -2

Anivarth
Anivarth

Reputation: 679

I am assuming that you are making a quiz kind of application. For this kind of application I have written a function which is as follows:

def shuffle(q):
"""
The input of the function will 
be the dictionary of the question
and answers. The output will
be a random question with answer
"""
selected_keys = []
i = 0
while i < len(q):
    current_selection = random.choice(q.keys())
    if current_selection not in selected_keys:
        selected_keys.append(current_selection)
        i = i+1
        print(current_selection+'? '+str(q[current_selection]))

If I will give the input of questions = {'VENEZUELA':'CARACAS', 'CANADA':'TORONTO'} and call the function shuffle(questions) Then the output will be as follows:

VENEZUELA? CARACAS
CANADA? TORONTO

You can extend this further more by shuffling the options also

Upvotes: 0

firelynx
firelynx

Reputation: 32214

This works in Python 2 and Python 3:

A random key:

random.choice(list(d.keys()))

A random value

random.choice(list(d.values()))

A random key and value

random.choice(list(d.items()))

Upvotes: 8

ziya efkar
ziya efkar

Reputation: 1

b = { 'video':0, 'music':23,"picture":12 } 
random.choice(tuple(b.items())) ('music', 23) 
random.choice(tuple(b.items())) ('music', 23) 
random.choice(tuple(b.items())) ('picture', 12) 
random.choice(tuple(b.items())) ('video', 0) 

Upvotes: -3

OBu
OBu

Reputation: 5177

Since the original post wanted the pair:

import random
d = {'VENEZUELA':'CARACAS', 'CANADA':'TORONTO'}
country, capital = random.choice(list(d.items()))

(python 3 style)

Upvotes: 5

user2778712
user2778712

Reputation:

Try this (using random.choice from items)

import random

a={ "str" : "sda" , "number" : 123, 55 : "num"}
random.choice(list(a.items()))
#  ('str', 'sda')
random.choice(list(a.items()))[1] # getting a value
#  'num'

Upvotes: -1

Milad Mohammad Rezaei
Milad Mohammad Rezaei

Reputation: 97

If you don't want to use random.choice() you can try this way:

>>> list(myDictionary)[i]
'VENEZUELA'
>>> myDictionary = {'VENEZUELA':'CARACAS', 'IRAN' : 'TEHRAN'}
>>> import random
>>> i = random.randint(0, len(myDictionary) - 1)
>>> myDictionary[list(myDictionary)[i]]
'TEHRAN'
>>> list(myDictionary)[i]
'IRAN'

Upvotes: 2

carl
carl

Reputation: 50554

Since this is homework:

Check out random.sample() which will select and return a random element from an list. You can get a list of dictionary keys with dict.keys() and a list of dictionary values with dict.values().

Upvotes: 1

Related Questions