简体   繁体   中英

Having trouble mapping a list to a list of lists in python

Essentially, I need to create a new list of lists from a value list that maps to another interval list. Some of these values actually fall in the range of two sublists in the intervals. For instance, 25 falls between [0,30] and between [20,55]. However an integer value such as 91 only falls in the range of one sublist [75,100]. I want to create a new list where each value maps to the interval list but I want these values separate from the interval list.

    intervals = [[0,30], [20,55], [45,80], [75,100]]
    values = [25, 51, 53, 83, 91]

Right now my code is as follows:

    maplist = [[]]
    for i in values:
        for j in intervals: 
            if(i >= j[0]) and (i <= j[1]):
                maplist.append(i)
    print(maplist)

This ouputs to: [[], 25, 25, 51, 51, 53, 53, 83, 91 ]

So, as you can see, Its outputting 25 twice, 51 twice and 53 twice because those values fall between various sublists. 83 and 91 only fall between [75-100]

I want the output to be:

    [[25], [25,51,53], [51,53], [83,91]]

This means each value would map with the interval list of lists. Any help would be greatly appreciated.

List comprehensions?

>>> [[v for v in values if a <= v <= b] for a, b in intervals]
[[25], [25, 51, 53], [51, 53], [83, 91]]

So you could do it by looping through intervals first and getting all the values in that range. Like this:

intervals = [[0,30], [20,55], [45,80], [75,100]]
values = [25, 51, 53, 83, 91]

maplist = []
for i in intervals:
    inrange = []
    for v in values:
        if v >= i[0] and v <= i[1]:
            inrange.append(v)
    maplist.append(inrange)

print(maplist)

This prints [[25], [25, 51, 53], [51, 53], [83, 91]]

The problem is that you are appending to maplist , which is initialized to be a list containing one element (another list). When you process 25, you append it to maplist , first once, at which point maplist is [[], 25] and then again for the next interval ( [[], 25, 25] ).

Instead, you want one list for each interval:

maplist = [[] for _ in range(len(intervals))]
for i in values:
    for idx, j in enumerate(intervals):
        if(i >= j[0]) and (i <= j[1]):
            maplist[idx].append(i)

(If you're not familiar with enumerate , it produces pairs (index, item) for the items in a list.)

Use a list comprehension.

Also you are initializing the maplist with another list..

maplist = [[x for x in values if i <= x <= j] for i, j in intervals]

print(maplist)

You can use collections.defaultdict to create a better mapping of the occurrences of each each value item in intervals :

from collections import defaultdict
d = defaultdict(list)
intervals = [[0,30], [20,55], [45,80], [75,100]]
values = [25, 51, 53, 83, 91]
for i in values:
  for c, h in enumerate(intervals):
     if i >= h[0] and i <= h[-1]:
         d[c].append(i)

final_result = [b for a, b in d.items()]

Output:

[[25], [25, 51, 53], [51, 53], [83, 91]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM