【问题标题】:Comparing Two List of Strings比较两个字符串列表
【发布时间】:2019-04-07 00:27:34
【问题描述】:

我熟悉比较 2 个整数和字符串列表;但是,在比较 2 个包含额外字符的字符串列表时可能会有点困难。

假设输出包含以下内容,我将其分解为字符串列表。 我在我的代码中称它为 diff。

输出

164c164
< Apples = 
---
> Apples = 0
168c168
< Berries = 
---
> Berries = false
218c218
< Cherries = 
---
> Cherries = 20
223c223
< Bananas = 
---
> Bananas = 10
233,234c233,234
< Lemons = 2
< Strawberries = 4
---
> Lemons = 4
> Strawberries = 2
264c264
< Watermelons = 
---
> Watermelons = 524288

第二组字符串包含我希望与第一个列表进行比较的忽略变量。

>>> ignore
['Apples', 'Lemons']

我的代码:

>>> def str_compare (ignore, output):
...     flag = 0
...     diff = output.strip ().split ('\n')
...     if ignore:
...         for line in diff:
...             for i in ignore:
...                 if i in line:
...                     flag = 1
...             if flag:
...                 flag = 0
...             else:
...                 print (line)
... 
>>>

代码适用于 Apple 和 Lemons 省略。

>>> str_compare(ignore, output)
164c164
---
168c168
< Berries = 
---
> Berries = false
218c218
< Cherries = 
---
> Cherries = 20
223c223
< Bananas = 
---
> Bananas = 10
233,234c233,234
< Strawberries = 4
---
> Strawberries = 2
264c264
< Watermelons = 
---
> Watermelons = 524288
>>>

必须有更好的方法来比较不是 O(n^2) 的 2 个字符串。如果我的差异列表不包含像“Apples =”这样的额外字符,那么可以使用 O(n) 比较两个列表。有什么建议或想法可以在不循环每个 diff 元素上的“忽略”变量的情况下进行比较?

更新 #1 为避免混淆并使用建议的注释,我更新了代码。

>>> def str_compare (ignore, output):
...     diff = output.strip ().split ('\n')
...     if ignore:
...         for line in diff:
...             if not any ([i in line for i in ignore]):
...                 print (line)
...                 print ("---")
>>>

不管怎样,它仍然会为每个 diff 元素循环忽略两次。

【问题讨论】:

  • 我很困惑,为什么不用if not any([i in line for i in ignore]): print(line) 而不是flag
  • 什么是 n。使用 SET 或 DICT 来提高速度
  • @RockyLi,这样做会打印两次,因为它会循环两次忽略列表。
  • 不,它没有。用该 sn-p 替换 for line in diff: 下的所有内容,它只会打印一次。当然,这并不能回答您的问题,因为它仍然是 O(n^2),但如果您担心,您可以使用 set,因为 set 操作在 O(1) 时间内完成。
  • @RockyLi,我的评论是在你编辑你的评论之前。如果使用if any,则不需要标志,但它仍然是2个嵌套的for循环。

标签: python list python-3.5 string-comparison


【解决方案1】:

为了提高效率,请使用忽略集合而不是列表。使用 split 从行获取关键字。

>>> def str_compare (ignore, output):
...     ignore = set (ignore)
...     diff = output.strip ().split ('\n')
...     for line in diff:
...         if line.startswith('<') or line.startswith('>'):
...             var = line.split () [1]
...             if var not in ignore:
...                 print (line)
...         else:
...             print (line)
... 

输出

>>> str_compare (ignore, output)
164c164
---
168c168
< Berries = 
---
> Berries = false
218c218
< Cherries = 
---
> Cherries = 20
223c223
< Bananas = 
---
> Bananas = 10
233,234c233,234
< Strawberries = 4
---
> Strawberries = 2
264c264
< Watermelons = 
---
> Watermelons = 524288

您可以通过拆分和连接“---\n”来消除对标志的需求(比标志或打字机更通用的解决方案----)

请注意,在 s2 最坏的情况下,字符串包含 s1 应该大约是 len(s1) * len(2),而相等大约是 max(len(s1),len(s2)。虽然 python 实现相当不错(对于平均情况),线性复杂度算法似乎存在http://monge.univ-mlv.fr/~mac/Articles-PDF/CP-1991-jacm.pdf 另见Algorithm to find multiple string matches

【讨论】:

  • 没有标志它会忽略数字
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-21
相关资源
最近更新 更多