从一组(相似)字符串中确定前缀

Kaw*_*awu 63 python string prefix

我有一组字符串,例如

my_prefix_what_ever
my_prefix_what_so_ever
my_prefix_doesnt_matter
Run Code Online (Sandbox Code Playgroud)

我只是想找到这些字符串中最长的公共部分,这里是前缀.在上面的结果应该是

my_prefix_
Run Code Online (Sandbox Code Playgroud)

字符串

my_prefix_what_ever
my_prefix_what_so_ever
my_doesnt_matter
Run Code Online (Sandbox Code Playgroud)

应该导致前缀

my_
Run Code Online (Sandbox Code Playgroud)

在Python中有一种相对无痛的方法来确定前缀(无需手动迭代每个字符)吗?

PS:我使用的是Python 2.6.3.

Ned*_*der 119

永远不要改写提供给你的东西:os.path.commonprefix这样做:

返回最长路径前缀(逐个字符),它是列表中所有路径的前缀.如果list为空,则返回空字符串('').请注意,这可能会返回无效路径,因为它一次只能处理一个字符.

为了与其他答案进行比较,这里是代码:

# Return the longest prefix of all list elements.
def commonprefix(m):
    "Given a list of pathnames, returns the longest common leading component"
    if not m: return ''
    s1 = min(m)
    s2 = max(m)
    for i, c in enumerate(s1):
        if c != s2[i]:
            return s1[:i]
    return s1
Run Code Online (Sandbox Code Playgroud)

  • 好的'Python'.具有我需要的功能,正是因为我需要它. (4认同)
  • 参数是否必须是有效的路径名?如果他们不这样做会发生什么?文档什么也没说,所以我不太确定这是否可以用于任意字符串。 (3认同)
  • 告诉 LC 面试官(“永远不要重写提供给你的内容”)。作为一个严肃的、也许是建设性的评论,请考虑实际上不提供该函数的源代码,因为乍一看我错过了它已经是“os.path.commonprefix”的一部分的声明 (3认同)
  • @sramij 不完全是!字符串上的 min() 和 max() 是字典中的最小值和最大值,就像字典中的一样。因此,当最小值和最大值具有相同的首字母时,它们之间的所有其他单词也必须具有相同的字母,依此类推。 (2认同)

sen*_*rle 13

Ned Batchelder可能是对的.但是为了它的乐趣,这是一个更有效的phimuemue使用的答案版本itertools.

import itertools

strings = ['my_prefix_what_ever', 
           'my_prefix_what_so_ever', 
           'my_prefix_doesnt_matter']

def all_same(x):
    return all(x[0] == y for y in x)

char_tuples = itertools.izip(*strings)
prefix_tuples = itertools.takewhile(all_same, char_tuples)
''.join(x[0] for x in prefix_tuples)
Run Code Online (Sandbox Code Playgroud)

作为对可读性的冒犯,这是一个单行的版本:)

>>> from itertools import takewhile, izip
>>> ''.join(c[0] for c in takewhile(lambda x: all(x[0] == y for y in x), izip(*strings)))
'my_prefix_'
Run Code Online (Sandbox Code Playgroud)

  • 对于 Python3,请将 `itertools.izip(*strings)` 替换为 `zip(*strings)`。 (2认同)

MRA*_*RAB 5

这是我的解决方案:

a = ["my_prefix_what_ever", "my_prefix_what_so_ever", "my_prefix_doesnt_matter"]

prefix_len = len(a[0])
for x in a[1 : ]:
    prefix_len = min(prefix_len, len(x))
    while not x.startswith(a[0][ : prefix_len]):
        prefix_len -= 1

prefix = a[0][ : prefix_len]
Run Code Online (Sandbox Code Playgroud)