Python list in list
I have two lists: ra_list
, e_list
.
ra_list
- a list of random numbers, e_list
is a list with sets of numbers and categorization.
The number from ra_list is compared with the number in e_list, and its category is indicated 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 this: 5 D, 5 D, 6 C, 7 B, 7 B
This works partially fine, however, when I have two numbers in two tuples with different categories, only one is counted and selected as the result (for example, the program states that 7 from ra_list is always B, but as you can see A is also 7)
Is it possible to implement a list in a list that will be randomized between A and B? Or, if there was another classification with the same number, for example. if A and B are 7 and C and D are 6, this randomly chooses A or B and C or D. I know I can randomize through the list with:
random.choice(list_of_duplicates)
But I am struggling on how to create a list of duplicates and join with the original list.
If anyone has a suggestion or can point me in the right direction, I would appreciate it. Thank!
EDIT
That ra_list is a float and therefore in the range between item 1 and item 2? eg.
ra_list = [7.53, 3.42, 35.64]
e_lst = [(a, 7), (b, 7), (c,8), (d,23)]
The output will be 7.53 a or b as its in the range between a, b and c.
source to share
If you want to randomly select, it would be easier to create a dictionary of values: category where category will be a list of categories and then you can use random.choice()
in that list.
For this you can use dict.setdefault
with the default as an empty list []
, this function sets the default to key
if it doesn't 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
source to share
Using list comprehension and random selection
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
Codex2:
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
source to share
First you can use a dictionary to store the numbers as a key and the corresponding characters in the list as values to use the c function 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 the following reference, this recipe will be much faster on large lists than @ Vignesh Kalai's answer, which called a function random
on each list and used a nested 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
source to share
You can create a dictionary of duplicate rater and then create a list of lists. Dick 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 result.
source to share