如果字符串列表的长度低于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元素的情况怎么样?
答案 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]