如何获取列表中字符串的公共前缀
How to get common prefix of strings in a list
我需要知道如何识别列表中字符串的前缀。例如,
list = ['nomad', 'normal', 'nonstop', 'noob']
它的答案应该是 'no' 因为列表中的每个字符串都以 'no'
开头
我想知道有没有一种方法可以同时遍历列表中字符串中的每个字母,并检查每个字母是否相同。
这是没有库的代码:
for i in range(len(l[0])):
if False in [l[0][:i] == j[:i] for j in l]:
print(l[0][:i-1])
break
给出输出:
no
使用os.path.commonprefix它会完全按照你的要求去做。
In [1]: list = ['nomad', 'normal', 'nonstop', 'noob']
In [2]: import os.path as p
In [3]: p.commonprefix(list)
Out[3]: 'no'
另外,将列表命名为 "list" 将无法访问 list
class,因此我建议使用不同的变量名称。
没有内置函数可以执行此操作。如果您正在寻找可以为您执行此操作的简短 python 代码,这是我的尝试:
def longest_common_prefix(words):
i = 0
while len(set([word[:i] for word in words])) <= 1:
i += 1
return words[0][:i-1]
说明:words
是一个可迭代的字符串。列表理解
[word[:i] for word in words]
使用字符串切片获取每个字符串的前 i
个字母。一开始,这些都是空字符串。然后,它将由每个单词的第一个字母组成。然后是前两个字母,以此类推。
转换为 set
会删除重复项。例如,set([1, 2, 2, 3]) = {1, 2, 3}
。通过将我们的前缀列表转换为一个集合,我们删除了重复项。如果集合的长度小于或等于一,那么它们都是相同的。
计数器 i
只记录到目前为止有多少字母是相同的。
我们returnwords[0][i-1]
。我们任意选择第一个单词并取前 i-1
个字母(这对于列表中的任何单词都是相同的)。它是 i-1
而不是 i
的原因是 i
在我们检查是否所有单词仍然共享相同的前缀之前递增。
这是一个有趣的例子:
l = ['nomad', 'normal', 'nonstop', 'noob']
def common_prefix(lst):
for s in zip(*lst):
if len(set(s)) == 1:
yield s[0]
else:
return
result = ''.join(common_prefix(l))
结果:
'no'
回答你问题的精神 - zip(*lst)
是让你 "iterate letters in every string in the list at the same time" 的原因。例如,list(zip(*lst))
看起来像这样:
[('n', 'n', 'n', 'n'), ('o', 'o', 'o', 'o'), ('m', 'r', 'n', 'o'), ('a', 'm', 's', 'b')]
现在您需要做的就是找出共同元素,即每个组的 set
中的 len
,如果它们是共同的 (len(set(s)) == 1
),则加入它回来了。
顺便说一句,您可能不想用名称 list
来称呼您的列表。之后任何时候你打电话给 list()
都会让人头疼。隐藏内置关键字是不好的做法。
我需要知道如何识别列表中字符串的前缀。例如,
list = ['nomad', 'normal', 'nonstop', 'noob']
它的答案应该是 'no' 因为列表中的每个字符串都以 'no'
开头我想知道有没有一种方法可以同时遍历列表中字符串中的每个字母,并检查每个字母是否相同。
这是没有库的代码:
for i in range(len(l[0])):
if False in [l[0][:i] == j[:i] for j in l]:
print(l[0][:i-1])
break
给出输出:
no
使用os.path.commonprefix它会完全按照你的要求去做。
In [1]: list = ['nomad', 'normal', 'nonstop', 'noob']
In [2]: import os.path as p
In [3]: p.commonprefix(list)
Out[3]: 'no'
另外,将列表命名为 "list" 将无法访问 list
class,因此我建议使用不同的变量名称。
没有内置函数可以执行此操作。如果您正在寻找可以为您执行此操作的简短 python 代码,这是我的尝试:
def longest_common_prefix(words):
i = 0
while len(set([word[:i] for word in words])) <= 1:
i += 1
return words[0][:i-1]
说明:words
是一个可迭代的字符串。列表理解
[word[:i] for word in words]
使用字符串切片获取每个字符串的前 i
个字母。一开始,这些都是空字符串。然后,它将由每个单词的第一个字母组成。然后是前两个字母,以此类推。
转换为 set
会删除重复项。例如,set([1, 2, 2, 3]) = {1, 2, 3}
。通过将我们的前缀列表转换为一个集合,我们删除了重复项。如果集合的长度小于或等于一,那么它们都是相同的。
计数器 i
只记录到目前为止有多少字母是相同的。
我们returnwords[0][i-1]
。我们任意选择第一个单词并取前 i-1
个字母(这对于列表中的任何单词都是相同的)。它是 i-1
而不是 i
的原因是 i
在我们检查是否所有单词仍然共享相同的前缀之前递增。
这是一个有趣的例子:
l = ['nomad', 'normal', 'nonstop', 'noob']
def common_prefix(lst):
for s in zip(*lst):
if len(set(s)) == 1:
yield s[0]
else:
return
result = ''.join(common_prefix(l))
结果:
'no'
回答你问题的精神 - zip(*lst)
是让你 "iterate letters in every string in the list at the same time" 的原因。例如,list(zip(*lst))
看起来像这样:
[('n', 'n', 'n', 'n'), ('o', 'o', 'o', 'o'), ('m', 'r', 'n', 'o'), ('a', 'm', 's', 'b')]
现在您需要做的就是找出共同元素,即每个组的 set
中的 len
,如果它们是共同的 (len(set(s)) == 1
),则加入它回来了。
顺便说一句,您可能不想用名称 list
来称呼您的列表。之后任何时候你打电话给 list()
都会让人头疼。隐藏内置关键字是不好的做法。