简体   繁体   中英

Short way to extract sublist from list in python by given conditions

I have particular problem which I have to make the most simple yet still reflecting issue, and need to know is there a short way to do it.

class Foo(object):
    def __init__(self, c):
        self.bar=c

objects = [Foo(x) for x in 'ab..$...$x.z']

Now we have list of objects and here is the problem; I have to shorten list to all objects with '.' between two with '$' bar attributes from left and right of given index. Index is returned by some calculation and should not necessarily hits object with bar='.' so in that case [] is returned.

So the [x.bar for x in objects] should be ['.','.','.'] . I tried to represent the problem by the most simple way, sorry for any inconvenience...

The point is, code should be short. Thank you.

You can use re to do that:

In case you have 1 substring:

objects = [x for x in re.search('\$(.*?)\$', 'ab..$...$x.z').groups()[0]]

In case you have unknown number of substrings:

objects = [y for x in re.finditer('\$(.*?)\$', 'ab..$123$x.,,,$abc$,,,') for y in x.groups()[0]]

You need to use a dictionary for get a collection of objects and use regex for get every thing between tow $ :

>>> objects = {'a%d'%i:Foo(x) for i,x in enumerate(list(re.search(r'\$(.*)\$','ab..$...$x.z').group(1)))}
>>> objects
{'a1': <__main__.Foo object at 0x7ff1a6952b90>, 'a0': <__main__.Foo object at 0x7ff1a6952a50>, 'a2': <__main__.Foo object at 0x7ff1a6952bd0>}
>>> objects['a0'].bar
'.'
>>> objects['a1'].bar
'.'
>>> objects['a2'].bar
'.'

then you can get the object list with objects.values() .

>>> obj=objects.values()
>>> [x.bar for x in obj]
['.', '.', '.']

and if you dont want to use dictionary and want the list of objects use a list comprehension like following :

>>> objects = [Foo(x) for x in list(re.search(r'\$(.*)\$','ab..$...$x.z').group(1))]
>>> [x.bar for x in objects]
['.', '.', '.']
class Foo(object):
    def __init__(self, c):
        self.bar=c

objects = [Foo(x) for x in 'ab..$111$x.z$222']

Get the indices of the sentinals

z = [i for i, thing in enumerate(objects) if thing.bar == '$']

Extract the objects between the sentinals using those indices.

for i,j in zip(z, z[1:]):
    print map(operator.attrgetter('bar'), objects[i+1:j])

>>> 
['1', '1', '1']
['x', '.', 'z']
>>> 

To create the list of objects - one sub-list for each interval between the sentinals:

what_i_want = [objects[i+1:j] for i,j in zip(z, z[1:])]

Try this :

objects = [Foo(x) for x in 'ab..$...$x.z'.split('$')[1]]

Output of [x.bar for x in objects] is ['.','.','.']

This is sure to work, for the given input (ie only two '$' symbol)

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