如何在Python中找到一个列表中的最短字符串

61

这似乎是一个相当简单的问题,但我正在寻找一种简短而易懂的方法来解决它(这不是代码高尔夫比赛)。

给定一个字符串列表,最简单的方法是什么来找到最短的字符串?

对我来说最明显的方式大致如下:

l = [...some strings...]
lens = map(l, len)
minlen, minind = min(lens)
shortest = l[minind]

但在 Python 中,看起来这需要写很多代码。

8个回答

181

函数min有一个可选参数key,可以用来指定一个函数来确定每个项目的“排序值”。我们只需要将其设置为len函数即可获取最短值:

strings = ["some", "example", "words", "that", "i", "am", "fond", "of"]

print min(strings, key=len) # prints "i"

3

Takes linear time:

   reduce(lambda x, y: x if len(x) < len(y) else y, l)

0
我会使用sorted(l, key=len)[0]

2
这太过犹豫。除了概念上过于复杂之外,排序是O(n log n)minO(n) - user395760
@delnan,我不知道是否同意“概念上复杂”,但我同意使用min更好(以及稍后发布的reduce变体)。 - carlpett
3
更不用说对于大量输入来说效率低下,它还会返回错误的结果——返回的是最长的字符串。至少已经修复了这个问题... - carlpett

0
另一种解决方法是使用显式循环。当可迭代对象为空时,此实现返回 None 。
def smallest_string(iterable):
    res = None
    for x in iterable:
        if res is None or len(x) < len(res):
            res = x
    return res

strings = ["some", "example", "words", "that", "i", "am", "fond", "of"]
print(smallest_string(strings))

空迭代器的行为是当前解决方案的主要区别因素。

  • min(iterable, key=len) 解决方案会引发 ValueError: min() arg is an empty sequence
  • functools.reduce(lambda x, y: x if len(x) < len(y) else y, iterable) 解决方案会引发 TypeError: reduce() of empty iterable with no initial value。给它一个初始值不起作用,因为 lambda 将使用该值调用。
  • sorted(iterable, key=len)[0] 引发 IndexError: list index out of range
  • 此实现返回 None。可以修改为返回空字符串或引发错误(可能使用 for + else 结构)。

-1
可能的答案:
l = [...some strings...]
l.sort(key=len)
shortest = l[0]

然而,这种方法可能非常低效,因为它对整个列表进行了排序,这是不必要的。我们只需要最小值。


1
这也会导致输入列表不再具有相同的顺序。min()将获取最左边的最短字符串,这是与list.sort()不同的另一种行为。看看这个例子:min(["arthur", "Arthur"], key=len)将返回"arthur",而提供的代码将返回"Arthur" - colidyre

-1
在列表中找到最短的字符串:
str = ['boy', 'girl', 'lamb', 'butterfly']

def len_str(string):
  return len(string)

def compare_len(list):
  x = []
  for i in range(len(list)):
    x.append(len_str(list[i]))
  return min(x) #change to max if you're looking for the largest length

compare_len(str)

1
为什么要定义一个函数 len_str,它只是 len 的包装器?另外,你应该迭代元素而不是索引:for x in y: res.append(len(x))。最后请注意,你覆盖了内置名称 strlist - Tomerikoo

-1

正如其他答案所建议的那样,这些解决方案需要线性时间。但是它们需要防止空迭代器:

import functools

strings = ["small str", "xs", "long string"]

if (strings):
    print( "shortest string:", functools.reduce(lambda x, y: x if len(x) < len(y) else y, strings) )
    # or if you use min:
    # print( "shortest string:", min(strings, key=len) )
else:
    print( "list of strings is empty" )

-2
arr=('bibhu','prasanna','behera','jhgffgfgfgfg')
str1=''

#print (len(str))
for ele in arr:
    print (ele,ele[::-1])
    if len(ele)>len(str1):
        str1=ele
    elif len(ele)<len(str2):
        str2=ele
print ("the longest element is :",str1)
str2=arr[0]
for ele in arr:
    if len(ele)<len(str2):
        str2=ele

print ("the shortest element is :",str2) 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接