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.

+3


source to share


4 answers


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

      

+1


source


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

      

+4


source


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

      

+2


source


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.

+1


source