【问题标题】:How do you find out if the string is a component of the preceding string如何确定字符串是否是前一个字符串的组成部分
【发布时间】:2013-04-21 03:09:51
【问题描述】:

我正在尝试编写一个函数,该函数将查看字符串列表并确定列表中的下一个字符串是否是前一个字符串的子字符串。

如果我有['Ryan', 'Rya', 'Ry', 'Testing', 'Test'] 的列表

我会回复['Ryan', 'Rya', 'Ry', 'Test']

我什至不确定从哪里开始。

【问题讨论】:

  • 为什么"Ryan" 会出现在结果中
  • 我建议为此编写一些小函数。你会发现这让事情变得更容易了。
  • 是的,因为没有什么可以与之比较的。
  • 我不明白。如果匹配的子字符串删除了前面的字符串,您应该留下 ['Ry', 'Test'] 我错过了什么?
  • 它不应该删除前面的字符串,只返回字符串,以便 Ryan 是第一个所以它保持,Rya 是 Ryan 的子字符串所以它保持等等等等测试不是t 是 Ry 的子字符串,因此它被忽略,但 Test 是测试的子字符串,因此被返回。

标签: python string list function


【解决方案1】:

您可以通过列表理解来完成此操作

def find_results(seq): #I'm sure you can name this function better
    return [seq[0]] + [current for previous, current in zip(seq, seq[1:]) 
                       if current in previous]

seq[1:] 是除了第一个元素之外的整个列表

zip(a, b) 为您传递的每个可迭代对象生成元素对。在这种情况下,前面的字符串和当前字符串。

in 运算符将测试一个字符串是否在另一个字符串中。 "test" in "testing" 是真的

理解说,对于每对字符串(当前和前一个),如果当前字符串是前一个字符串的子字符串,则构造一个所有当前字符串的列表

【讨论】:

  • +1 被命名为 Ryan。你能把你的姓改成“Testing”吗?
  • @TimPietzcker 哈哈,如果我不用等一个月就可以改回来
  • 当我这样做时,我只得到前两个,所以 Ryan 和 Rya 我没有得到测试
  • @blandman1990 它对我来说很好用。你的案子关了吗?因为'test' in 'Testing' 将是错误的(注意大写“T”)
  • 你知道什么时候有人删除了他们的 cmets,然后你看起来就像在自言自语吗?哈哈。
【解决方案2】:

你可以这样做:

def f(lst):
    yield lst[0]

    for i in range(1, len(lst)):
        prev_string = lst[i - 1]
        curr_string = lst[i]

        if curr_string in prev_string:
            yield curr_string

f 将是一个生成器,因此要将其转换为列表,请将其传递给 list

In [36]: f(['Ryan', 'Rya', 'Ry', 'Testing', 'Test'])
Out[36]: <generator object f at 0x02F75F08>

In [37]: list(f(['Ryan', 'Rya', 'Ry', 'Testing', 'Test']))
Out[37]: ['Ryan', 'Rya', 'Ry', 'Test']

【讨论】:

    【解决方案3】:

    你可以这样做:

    l = ['Ryan', 'Rya', 'Ry', 'Testing', 'Test'] 
    r = []
    for i in range(1, len(l)):
      if l[i] in l[i - 1]:
        r.append(l[i])
    

    或使用列表理解:

    r = [l[i] for i in range(1,len(l)) if l[i] in l[i - 1]]
    

    【讨论】:

    • 列表解析将导致第一个元素与最后一个元素进行比较。 l[0-1]
    • 次要吹毛求疵:不要使用l 作为变量名。我建议使用L
    • 工作了一些,让它做我想做的事,谢谢
    【解决方案4】:

    Ryan Haining's answer 的启发,我编写了一个基于生成器的版本,它适用于任何可迭代对象,而不仅仅是序列:

    #!/usr/bin/env python2
    from itertools import izip, tee
    
    def find_results(iterable):
        icur, iprev = tee(iterable)
        yield next(icur)
        for i in (cur for cur, prev in izip(icur, iprev) if cur in prev):
            yield i
    
    print list(find_results(['Ryan', 'Rya', 'Ry', 'Testing', 'Test']))
    

    Python 3 版本略短:

    #!/usr/bin/env python3
    from itertools import tee
    
    def find_results(iterable):
        icur, iprev = tee(iterable)
        yield next(icur)
        yield from (cur for cur, prev in zip(icur, iprev) if cur in prev)
    
    print(list(find_results(['Ryan', 'Rya', 'Ry', 'Testing', 'Test'])))
    

    【讨论】:

      【解决方案5】:

      受@CristianCiupitu 启发,但我觉得他的写作方式令人困惑。这是它的简化版本。

      >>> from itertools import izip, tee
      >>> def find_results(iterable):
          a, b = tee(iterable)
          yield next(a)
          for cur, prev in izip(a, b):
              if cur in prev:
                  yield cur
      
      
      >>> print(list(find_results(['Ryan', 'Rya', 'Ry', 'Testing', 'Test'])))
      ['Ryan', 'Rya', 'Ry', 'Test']
      

      【讨论】:

      • +1 确实,Python 2 的解决方案可能有点难以阅读,因为我想展示生成器的强大功能。
      猜你喜欢
      • 2013-09-06
      • 1970-01-01
      • 1970-01-01
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-24
      • 2011-01-17
      相关资源
      最近更新 更多