简体   繁体   中英

python list of lists access element by cumulative index

Say I have a nested list that looks something like:

[
    [
        ['a', 'b', 'c'],
        ['d', 'e'],
        ['f', 'g', 'h', 'i']
    ], 
    [
        ['j'], 
        ['k', 'l'], 
        ['m', 'n', 'o']
    ], 
    [
        ['p'], 
        ['q']
    ]
]

How would I quickly access the n-th cumulative item in this list? So that I could ask for item #13 and get a reference to 'm' ? This needs to be very fast as I have to do this multiple times a second in my program.

Based on your comment "what I really need is to be able to find the regular indexes by cumulative indexes so I can do stuff like delete the 2nd level list that contains cumulative item #10", this should do what you want: not only flatten the list, but keep track of the path you used to get there:

def flatten(l, path=()):
    if not isinstance(l, list):
        yield path, l
        return

    for i, x in enumerate(l):
        for subpath, sub in flatten(x):
            yield (i,) + subpath, sub

This gives you a generator, so you either have to convert it into a list:

>>> f = [ [ ... 
>>> res = list(flatten(f))
>>> print res[2]
((0, 0, 2), 'c')
>>> print res[10]
((1, 1, 0), 'k')
>>> print res[12]
((1, 2, 0), 'm')

Or, perhaps better yet, create a function to take the nth item from the generator. If your list is huge and this is towards the start of the list, it won't even have to generate the rest:

def nth(it, n):
    for i, val in enumerate(it):
        if i == n:
            return val

And then:

>>> print nth(flatten(f), 2)
((0, 0, 2), 'c')
>>> print nth(flatten(f), 10)
((1, 1, 0), 'k')
>>> print nth(flatten(f), 12)
((1, 2, 0), 'm')

Thus: the second element is 'c' , which is in f[0][0][2] , the 10th element is 'k' , which is in f[1][1][0] , and the 12th element is 'm' , which is in f[1][2][0] .

I would traverse the list. This actually requires very little code in python 3:

def flat(elem):
    if isinstance(elem, list):
        for e in elem:
            yield from flat(e)
    else:
        yield elem

with your data stored in lst :

list(e for e in flat(lst))[12]
>>> 'm'

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