所以从字符串列表开始,如下所示
string_list = ["休息"、"休息"、"看"、"看"、"它"、"吐"]
我想从列表中删除任何作为另一个元素的子字符串的元素,例如给出结果......
string_list = ['休息', '看', '吐']
我有一些代码可以实现这一点,但它令人尴尬地丑陋,而且可能不必要的复杂。有没有一种简单的方法可以在 Python 中做到这一点?
第一个构建块:子字符串。
您可以使用in
来检查:
>>> 'rest' in 'resting'
True
>>> 'sing' in 'resting'
False
接下来,我们将选择创建新列表的朴素方法。我们将逐个将项目添加到新列表中,检查它们是否是子字符串。
def substringSieve(string_list):
out = []
for s in string_list:
if not any([s in r for r in string_list if s != r]):
out.append(s)
return out
您可以通过排序来加快速度以减少比较次数(毕竟,较长的字符串永远不能是较短/等长字符串的子字符串):
def substringSieve(string_list):
string_list.sort(key=lambda s: len(s), reverse=True)
out = []
for s in string_list:
if not any([s in o for o in out]):
out.append(s)
return out
这是一个可能的解决方案:
string_list = ['rest', 'resting', 'look', 'looked', 'it', 'spit']
def string_set(string_list):
return set(i for i in string_list
if not any(i in s for s in string_list if i != s))
print(string_set(string_list))
打印输出:
set(['looked', 'resting', 'spit'])
请注意,我创建了一个集合(使用生成器表达式)来删除可能重复的单词,因为顺序似乎无关紧要。
另一个行:
[string for string in string_list if len(filter(lambda x: string in x,string_list)) == 1]
应该相当可读,只是不是那么 pythonic。
这里有一种方法:
def find_unique(original):
output = []
for a in original:
for b in original:
if a == b:
continue # So we don't compare a string against itself
elif a in b:
break
else:
output.append(a) # Executed only if "break" is never hit
return output
if __name__ == '__main__':
original = ['rest', 'resting', 'look', 'looked', 'it', 'split']
print find_unique(original)
它利用了一个事实,即我们可以通过使用 in
运算符轻松检查一个字符串是否是另一个字符串的子字符串。它基本上遍历每个字符串,检查它是否是另一个字符串的子字符串,如果不是,则将其附加到输出列表中。
这将打印出['resting', 'looked', 'split']
这里有一个单行代码,可以做你想要的:
filter(lambda x: [x for i in string_list if x in i and x != i] == [], string_list)
例:
>>> string_list = ['rest', 'resting', 'look', 'looked', 'it', 'spit']
>>> filter(lambda x: [x for i in string_list if x in i and x != i] == [], string_list)
['resting', 'looked', 'spit']
这是有效的方法(相对于上述解决方案;)),因为这种方法大大减少了列表元素之间的比较次数。如果我有一个很大的列表,我肯定会选择这个,当然你可以把这个解决方案变成一个lambda函数,让它看起来很小:
string_list = ['rest', 'resting', 'look', 'looked', 'it', 'spit']
for item in string_list:
for item1 in string_list:
if item in item1 and item!= item1:
string_list.remove(item)
print string_list
输出:
>>>['resting', 'looked', 'spit']
希望对您有所帮助!
这是一种非最佳方法,仅在列表较小时使用:
for str1 in string_list:
for str2 in string_list:
if str1 in str2 and str1 != str2:
string_list.remove(str1)
这是另一种方法。假设您有一个排序列表要开始,并且您不必就地进行筛分,我们可以一次选择最长的字符串:
string_list = sorted(string_list)
sieved = []
for i in range(len(string_list) - 1):
if string_list[i] not in string_list[i+1]:
sieved.append(string_list[i])