如果字符串列表的长度低于Python 2.7中具有最大长度的字符串的长度,如何从字符串列表中删除字符串?

时间:2013-12-06 17:20:20

标签: python list string-length

如果字符串列表的长度低于Python 2.7中具有最大长度的字符串的长度,如何从字符串列表中删除字符串?

基本上,如果我有一个列表,如:

test = ['cat', 'dog', 'house', 'a', 'range', 'abc']
max_only(test)

输出应为:

['house', 'range']

'cat'的长度为3,'dog'为3,'house'为5,'a'为1,'range'为5,'abc'为3.长度最长的字符串为'房子'和'范围',所以他们回来了。

我尝试过类似的东西,当然,它不起作用:)

def max_only(lst):
    ans_lst = []
    for i in lst:
        ans_lst.append(len(i))   
        for k in range(len(lst)):
            if len(i) < max(ans_lst):
                lst.remove(lst[ans_lst.index(max(ans_lst))])
    return lst

你能帮帮我吗?

谢谢。

编辑:min length元素的情况怎么样?

5 个答案:

答案 0 :(得分:6)

使用列表推导和max

>>> test = ['cat', 'dog', 'house', 'a', 'range', 'abc']
>>> max_ = max(len(x) for x in test)    #Find the length of longest string.
>>> [x for x in test if len(x) == max_] #Filter out all strings that are not equal to max_
['house', 'range']

答案 1 :(得分:4)

只循环一次的解决方案:

def max_only(lst):
    result, maxlen = [], -1
    for item in lst:
        itemlen = len(item)
        if itemlen == maxlen:
            result.append(item)
        elif itemlen > maxlen:
            result[:], maxlen = [item], itemlen
    return result

max(iterable)必须遍历整个列表一次,并且挑选匹配长度的项目的列表理解必须再次遍历列表 。上面的版本只在输入列表中循环一次。

如果您的输入列表不是序列而是迭代器,则此算法仍然有效,而任何必须使用max()的算法都不会;为了找到最大长度,它已经耗尽了迭代器。

长度为1到9的100个随机单词的时间比较,重复100万次:

>>> import timeit
>>> import random
>>> import string
>>> words = [''.join([random.choice(string.ascii_lowercase) for _ in range(1, random.randrange(11))]) for _ in range(100)]
>>> def max_only(lst):
...     result, maxlen = [], -1
...     for item in lst:
...         itemlen = len(item)
...         if itemlen == maxlen:
...             result.append(item)
...         elif itemlen > maxlen:
...             result[:], maxlen = [item], itemlen
...     return result
... 
>>> timeit.timeit('f(words)', 'from __main__ import max_only as f, words')
23.173006057739258
>>> def max_listcomp(lst):
...     max_ = max(len(x) for x in lst)
...     return [x for x in lst if len(x) == max_]
>>> timeit.timeit('f(words)', 'from __main__ import max_listcomp as f, words')
36.34060215950012

result.append()循环之外使用缓存的r_append = result.append替换for会再削减2秒:

>>> def max_only(lst):
...     result, maxlen = [], -1
...     r_append = result.append
...     for item in lst:
...         itemlen = len(item)
...         if itemlen == maxlen:
...             r_append(item)
...         elif itemlen > maxlen:
...             result[:], maxlen = [item], itemlen
...     return result
... 
>>> timeit.timeit('f(words)', 'from __main__ import max_only as f, words')
21.21125817298889

根据受欢迎的请求,min_only()版本:

def min_only(lst):
    result, minlen = [], float('inf')
    r_append = result.append
    for item in lst:
        itemlen = len(item)
        if itemlen == minlen:
            r_append(item)
        elif itemlen < minlen:
            result[:], minlen = [item], itemlen
    return result

更有趣的是,一个完全不同的方法:按长度排序:

from itertools import groupby

def max_only(lst):
    return list(next(groupby(sorted(lst, key=len, reverse=True), key=len))[1])[::-1] 

def min_only(lst):
    return list(next(groupby(sorted(lst, key=len), key=len))[1]) 

这些工作通过按长度排序,然后挑选出具有相同长度的第一组单词。对于max_only(),我们需要反向排序,然后重新反转结果。排序具有O(NlogN)成本,这使得效率低于此处其他答案中的O(2N)解决方案或上面的O(N)解决方案:

>>> timeit.timeit('f(words)', 'from __main__ import max_only_sorted as f, words')
52.725801944732666

尽管如此,分拣方法还是给你一个有趣的单行。

答案 2 :(得分:3)

您可以使用max()返回列表中最大的项目。

>>> len_max = len(max(test, key=len))
>>> [x for x in test if len(x) == len_max]
['house', 'range']

如果然后取出与元素长度相同的所有字符串,则得到所需的结果。

答案 3 :(得分:2)

>>> test = ['cat', 'dog', 'house', 'a', 'range', 'abc']
>>> filter(lambda x,m=max(map(len, test)):len(x)==m, test)
['house', 'range']

对于Python3.x,您需要使用list(filter(...))

答案 4 :(得分:1)

这有效:

max_len = len(max(test, key=len))

result = [word for word  in test if len(word) == max_len]