从现有lis创建较小的列表

2024-05-19 03:20:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个清单,是这样的:

>>> list1 = ['Mary','had','a','little','lamb','which','was','very','naughty']

我需要从list1中创建另一个列表(list2),该列表是通过迭代list1并找到元素little,然后将littlelittle后面的每个元素附加到list2而创建的。你知道吗

做了一点阅读,发现从itertools的dropwhile只是为我的要求。你知道吗

>>> from itertools import dropwhile
>>> list2 = list(dropwhile(lambda l: 'little' not in l, list1))
>>> list2
['little', 'lamb', 'which', 'was', 'very', 'naughty']

完全符合我的要求。你知道吗

但是,现在我需要将结束元素指定为好吧,那又怎样我想要一个从非常的元素列表,包括以下两个:

>>>list3
['little', 'lamb', 'which', 'was', 'very']

我该如何用类似的方法做到这一点?你知道吗


Tags: from元素which列表veryitertoolsmarywas
3条回答

不使用itertools的简单方法可能如下所示:

start = list1.index("little")
end = list1.index("very")
list3 = list1[start:end+1]

或者简单地写为:

list3 = list1[list1.index("little"):list1.index("very")+1]

可以使用自定义函数返回生成器:

def drop(iterable,start,end):

    for i,x in enumerate(iterable):
        if x==start :
            for y in iterable[i:]:
                if y!=end:
                    yield y
                else:
                    yield end
                    break

演示:

list1 = ['Mary','had','a','little','lamb','which','was','very','naughty']
print list(drop(list1,'little','very'))
['little', 'lamb', 'which', 'was', 'very']

注意这个解决方案比使用list.index要快,因为它的顺序是O(n),您使用它2次,但是对于前面的函数,您在iterable[i:]中对所有列表进行1次迭代,另外还有一个索引,它的顺序小于O(n),所以速度更快。你知道吗

为了更好地理解,请查看以下基准:

from timeit import timeit

s1="""
list1 = ['Mary','had','a','little','lamb','which','was','very','naughty']
list1[list1.index("little"):list1.index("very")+1]
"""
s2="""
def drop(iterable,start,end):

    for i,x in enumerate(iterable):
        if x==start :
            for y in iterable[i:]:
                if y!=end:
                    yield y
                else:
                    yield end
                    break
list1 = ['Mary','had','a','little','lamb','which','was','very','naughty']
drop(list1,'little','very')
    """


print ' first: ' ,timeit(stmt=s1, number=1000000)
print 'second : ',timeit(stmt=s2, number=1000000)

结果:

 first:  5.87736296654
second :  5.01044201851 

如果希望继续使用itertools(不关心性能):

from itertools import dropwhile
list1 = ['Mary','had','a','little','lamb','which','was','very','naughty']

list2 = list(dropwhile(lambda x: x!="little", list1))
list3 = list(dropwhile(lambda x: x!="very", reversed(list2)))
print list(reversed(list3))

输出:

['little', 'lamb', 'which', 'was', 'very']

如果您关心性能,您应该定义一个自定义逻辑(感谢@Kasra):

list1 = ['Mary','had','a','little','lamb','which','was','very','naughty']

def drop(sequence,start,end):
    keep = False
    for item in sequence:
        if item == start:
            keep = True
        if keep and item == end:
            yield item
            break
        if keep:
            yield item

list3 = drop(list1, 'little', 'very')

print list(list3)

相关问题 更多 >

    热门问题