Reputation: 1093
I have two lists: ra_list
, e_list
.
ra_list
is a list of random numbers, e_list
is a list with tuples consisting on a number and a categorisation.
A number from ra_list is compared to the number in e_list, and its category is given, as follows:
ra_list = [5,5,6,7,7]
e_list = [(7, A), (7, B), (6, C), (5,D)]
for x in ra_list:
val = None
for i in xrange(0,len(e_list)-1):
if x[1] >= e_list[i][1] and x[1] < e_list[i+1][1]:
val = e_list[i][0]
if val == None:
val = e_list[-1][0]
print x, val
The current output looks like: 5 D, 5 D, 6 C, 7 B, 7 B
This runs partially fine, however when I have two numbers within two tuples with diferente categorisations only one is considered and selected as result (e.g. the program states that a 7 from ra_list is always B, but, as you can see, A is also 7)
Is it possible to implement a list within a list that will randomise between A and B? Or if there was another categorisation with the same number, e.g. if A and B were 7 and C and D were 6, it'd randomly pick A or B and C or D. I know that I can randomise through a list with:
random.choice(list_of_duplicates)
But I'm struggling on how to create the list of duplicates and join it with the original list.
If anyone has a suggestion or can point me in the right direction I'd appreciate it. Thank you!
EDIT
What it ra_list are floats, and thus in the range between element 1 and element 2? e.g.
ra_list = [7.53, 3.42, 35.64]
e_lst = [(a, 7), (b, 7), (c,8), (d,23)]
Output would be 7.53 a or b as its in the range between a,b and c.
Upvotes: 3
Views: 720
Reputation: 8335
Using list comprehension and random choice
Code:
ra_list = [5,5,6,7,7]
e_list = [(7, 'A'), (7, 'B'), (6, 'C'), (5,'D')]
import random
for element in ra_list:
print random.choice([value for value in e_list if element == value[0]])
(5, 'D')
(5, 'D')
(6, 'C')
(7, 'B')
(7, 'A')
Code1:
import random
ra_list = [5,5,6,7,7]
e_list = [(7, 'A'), (7, 'B'), (6, 'C'), (5,'D')]
for element in ra_list:
print element,random.choice([value[1] for value in e_list if element == value[0]])
output:
5 D
5 D
6 C
7 A
7 B
Code2:
ra_list = [7.84, 8.09, 7.40]
e_list= [('a', 7.31), ('b', 7.31), ('c', 8.08),('d',7.84)]
import random
for element in ra_list:
check_list=[value for value in e_list if element == value[1]]
if len(check_list)>0:
print random.choice(check_list)
else:
print element,"No-match"
Output:
('d', 7.84)
8.09 No-match
7.4 No-match
Code3:
ra_list = [7.53, 3.42, 35.64]
e_lst = [('a', 7), ('b', 7), ('c',8), ('d',23)]
import random
for element in ra_list:
check_list=[value for value in e_lst if round(element) == value[1]]
if len(check_list)>0:
print random.choice(check_list)
else:
print element,"No-match"
Output:
('c', 8)
3.42 No-match
35.64 No-match
Upvotes: 4
Reputation: 91007
If you want to randomly select , it would be easier to create a dictionary of the values:category , where category would be a list of categories , and then you can use random.choice()
on that list.
For this you can use dict.setdefault
with the default value as an empty list []
, this function sets the default value to key
if it does not exist, otherwise it returns the value for the key passed to it.
Example -
ra_list = [5,5,6,7,7]
e_list = [(7, 'A'), (7, 'B'), (6, 'C'), (5,'D')]
cate_dict = {}
#Creating dictionary of categories
for key,val in e_list:
cate_dict.setdefault(key,[]).append(val)
import random
for i in ra_list:
cate = random.choice(cate_dict.get(i,[0])) #To handle cases where `i` does not have category, if this is not the case then you do not need the second argument to `.get`. Use something other than `0` if that is one of the categories.
if cate != 0: #To handle cases where `cate` is someother value that can be false in boolean context.
print i,cate
Demo -
>>> ra_list = [5,5,6,7,7]
>>> e_list = [(7, 'A'), (7, 'B'), (6, 'C'), (5,'D')]
>>>
>>> cate_dict = {}
>>>
>>> #Creating dictionary of categories
... for key,val in e_list:
... cate_dict.setdefault(key,[]).append(val)
...
>>> import random
>>> for i in ra_list:
... cate = random.choice(cate_dict.get(i,[0]))
... if cate != 0:
... print(i,cate)
...
5 D
5 D
6 C
7 B
7 A
Upvotes: 1
Reputation: 107357
First you can use a dictionary to preserve the numbers as a key and the corresponding characters in a list as values the use a function with yield
to return a generator based on your condition :
>>> def printer(ra,e_list.d={}):
... for i,j in e_list:
... d.setdefault(i,[]).append(j)
... for i in ra:
... val=d.get(i)
... if len(val)==1:
... yield i,val[0]
... else :
... yield i,random.choice(val)
Demo :
>>> import random
>>> list(printer(ra_list,e_list))
[(5, 'D'), (5, 'D'), (6, 'C'), (7, 'B'), (7, 'B')]
>>> list(printer(ra_list,e_list))
[(5, 'D'), (5, 'D'), (6, 'C'), (7, 'B'), (7, 'A')]
>>>
Note that based on following benchmark this recipe would be pretty much faster on greater lists than @Vignesh Kalai's answer that called the random
function on each list and used a nested for loop :
from timeit import timeit
s1="""
ra_list = [5,5,6,7,7]*100
e_list = [(7, 'A'), (7, 'B'), (6, 'C'), (5,'D')]
for element in ra_list:
random.choice([value for value in e_list if element == value[0]])
"""
s2="""
ra_list = [5,5,6,7,7]*100
e_list = [(7, 'A'), (7, 'B'), (6, 'C'), (5,'D')]
def printer(ra,e_list,d={}):
for i,j in e_list:
d.setdefault(i,[]).append(j)
for i in ra:
val=d.get(i)
if len(val)==1:
yield i,val[0]
else :
yield i,random.choice(val)
list(printer(ra_list,e_list))
"""
print '1st: ' ,timeit(stmt=s1, number=1000,setup='import random')
print '2nd : ',timeit(stmt=s2, number=1000,setup="import random")
result :
1st: 3.390841960907
2nd : 1.092016124725
Upvotes: 2
Reputation: 1468
You can create a dictionary of duplicates rater then creating a list of lists. Dict will be cleaner.
e_list = [(7, 'A'), (7, 'B'), (6, 'C'), (5,'D')]
from collections import defaultdict
res_dict = defaultdict(list)
for item in e_list:
res_dict[item[0]].append(item[1])
print res_dict #defaultdict(<type 'list'>, {5: ['D'], 6: ['C'], 7: ['A', 'B']})
Now you can go ahead and add your logic to get the desired output.
Upvotes: 1