Alejandro R.
Alejandro R.

Reputation: 17

Get a random value from a list and its position at the same time in Python

I was wondering if there's a way in Python to get from a list, a random value of it and its position at the same time.

I know I can do this in two steps:

list_index = random.randrange(len(my_list))
list_value = my_list[index]

Also I want to exclude if there's a 0 value inside the list. I can't use random() 1st for getting a position because this way I need to recursively call random() until I don't get a 0.

Another posibility is to call random() to get values inside the list and exclude the 0, but with this implementation if, for example, there're two (or more) indentical values, Python outputs me the 1st position:

Example:

    [3 5 6 8 5 0]
    Random's output value = 5
    Position = 1

    But 5 value is also in position 4

How can I implement this? Is it feasible? I've been thinking and searching on the web so much, but couldn't find anything.

Really thank you in advance.

Alex

Upvotes: 0

Views: 1360

Answers (3)

Patrick Artner
Patrick Artner

Reputation: 51683

Up to python 3.7 you can use a list of the enumerate()d values of your list - this might break in long lists due to memory consumption:

data = [3, 5, 6, 8, 5, 7]

import random

pos, item = random.choice(list(enumerate(data)))

print("pos:", pos, "itemvalue:", item)

Output:

pos: 2 itemvalue: 6

With python 3.8 you can use the walrus operator which makes it viable for any-lenght lists:

data = [3, 5, 6, 8, 5, 7]

import random 
print("pos:", p := random.choice(range(len(data))), "itemvalue:", data[p]) 

Output:

pos: 0 itemvalue: 3

The 1st variant chooses from tuples that contains the position and the value - the 2nd variant chooses a random index into the list and acceses the liston that position to get the value.


You get random values from your input list - to avoid zeros you can loop until you get a non-zero value:

data = [0, 0, 5, 0, 0, 5, 0, 0, 5]

import random

for _ in range(10):
    item = 0
    while item == 0:
        pos, item = random.choice(list(enumerate(data)))
        # pos, item = (p := random.choice(range(len(data))), data[p]) 
    print("pos:", pos, "itemvalue:", item)

Output:

pos: 8 itemvalue: 5     
pos: 8 itemvalue: 5
pos: 5 itemvalue: 5
pos: 8 itemvalue: 5
pos: 2 itemvalue: 5
pos: 5 itemvalue: 5
pos: 2 itemvalue: 5
pos: 8 itemvalue: 5
pos: 5 itemvalue: 5
pos: 8 itemvalue: 5

Upvotes: 1

Mace
Mace

Reputation: 1410

Your question is not very clear to me but as I understand it your idea should be oké and should work fine.

You get the first 5's index when calling my_list.index(5). But you don't use this.

You get a random index and the value at this index which can also be the second 5.

import random

my_list = [3, 5, 6, 0, 8, 5, 7,]

# example of using index()
print(f"This is the first 5's index {my_list.index(5)}")
print()

for i in range(10):

    random_index = random.randrange(len(my_list))
    value = my_list[random_index]
    if value > 0:
        print(f'At position {random_index} the number is {value}')
    else:
        print(f'     Skipping position {random_index} the number is ZERO!')

Result

This is the first 5's index 1

At position 6 the number is 7
At position 6 the number is 7
At position 0 the number is 3
     Skipping position 3 the number is ZERO!
At position 4 the number is 8
At position 1 the number is 5
At position 5 the number is 5
At position 1 the number is 5
At position 1 the number is 5
At position 4 the number is 8

As you can see your method gets index 1 as well as index 5 for the number 5 in the list.

Upvotes: 1

ZaO Lover
ZaO Lover

Reputation: 433

Well, you can use filter function for doing that you want.

res_list = list(filter(lambda x: my_list[x] == random_value, range(len(my_list)))) 

The code above, res_list stores a list which contains indices.

Upvotes: 0

Related Questions