【问题标题】:Iterating through list, ignoring duplicates遍历列表,忽略重复项
【发布时间】:2018-04-12 18:10:53
【问题描述】:

我编写了一个程序,它试图在字母列表 (letterList) 中找到一系列字母(toBeFound - 这些字母代表一个单词),但是它拒绝承认当前的 3 个字母系列,因为它计算了'I' 在第一个列表中出现两次,将其添加到重复列表中。

目前此代码返回“不正确”,而它应该返回“正确”。

letterList= ['F','I',  'I',  'X',  'O',  'R',  'E']
toBeFound = ['F', 'I', 'X']

List = []
for i in toBeFound[:]:
    for l in letterList[:]:
        if l== i:
            letterList.remove(l)
            List.append(i)
if List == toBeFound:
    print("Correct.")
else:
    print("Incorrect.")

letterList 和 toBeFound 是样本值,每个中的字母可以是任何值。我无法设法遍历代码并成功确保忽略重复项。任何帮助将不胜感激!

【问题讨论】:

  • 为什么不把 letterList 做成一个集合呢?
  • 我的猜测是相对顺序很重要。
  • 我建议您将条件从if l==i 更改为if l==i and not l in List:
  • @bertew 您是否只想删除 连续重复项(彼此并排的),还是子列表的顺序根本不重要?即['X', 'X', 'F', 'I'] 中的['F', 'I', 'X'] 应该是真的吗?
  • 看起来真的是XY problem。你想达到什么目的? 如果 list1 按该顺序包含 list2 中的字符"".join(list2) in "".join(list1)如果 list2 元素在 list1 中all([x in list1 for x in list2]) 还是什么?

标签: python python-3.x list for-loop iteration


【解决方案1】:

基本上,您要查看toBeFound 是否是letterList子集,对吗?

这是使用sets 的提示:

In [1]: letters = set(['F','I',  'I',  'X',  'O',  'R',  'E'])

In [2]: find = set(['F', 'I', 'X'])

In [3]: find.issubset(letters)
Out[3]: True

In [4]: find <= letters
Out[4]: True

(顺便说一句,[3] 和 [4] 是同一运算符的不同表示法。)

【讨论】:

  • 我不确定。看起来他们正在寻找一个子列表而不是一个子集。例如,如果 toBeFound 包含一个像“hello”这样的词,那么你不能使用子集来找到它。你会被“helo”困住
  • OP 声明 FIX 应该与 FIIXORE 匹配。这排除了子列表。
  • 看我不同意。在给定的示例中,FIX 是所需的单词,输入是 FIIXORE。所需单词中没有重复项。我的建议是,如果您将 HELLO 作为所需的单词并输入 HEMLALOWL,您可能仍然希望该输入有效,因为它按顺序包含 HELLO。
  • 根据 OP 的评论,顺序似乎并不重要。
  • 很公平,我采用的方法实际上并不关心顺序,但我仍然很确定它是一个子列表而不是基于示例的子集
【解决方案2】:

我认为这会解决您的问题。请尝试并告诉我

letterList= ['F','I',  'I',  'X',  'O',  'R',  'E']
toBeFound = ['F', 'I', 'X']

found_list = [i for i in toBeFound if i in letterList]

print("Correct" if toBeFound == found_list else "Incorrect")

【讨论】:

    【解决方案3】:

    您可以将初始列表设置为一组,但如果您想查找像“hello”这样的单词,它不会起作用,因为您需要两个 l。

    解决这个问题的一种方法是使用字典来检查并了解我们目前的表现。

    letterList = ['H', 'E', 'L', 'X', 'L', 'I', 'O']
    toBeFound = ['H', 'E', 'L', 'L', 'O']
    
    # build dictionary to hold our desired letters and their counts
    toBeFoundDict = {}
    for i in toBeFound:
        if i in toBeFoundDict:
            toBeFoundDict[i] += 1
        else:
            toBeFoundDict[i] = 1
    
    letterListDict = {} # dictionary that holds values from input
    output_list = [] # dont use list its a reserved word
    for letter in letterList:
        if letter in letterListDict: # already in dictionary
    
            # if we dont have too many of the letter add it
            if letterListDict[letter] < toBeFoundDict[letter]:
                output_list.append(letter)
    
            # update the dictionary
            letterListDict[letter] += 1
    
    
        else: # not in dictionary so lets add it
    
            letterListDict[letter] = 1
    
            if letter in toBeFoundDict:
                output_list.append(letter)
    
    
    
    if output_list == toBeFound:
        print('Success')
    else:
        print('fail')
    

    【讨论】:

      【解决方案4】:

      这个怎么样:(我在python3.6中测试过)

      import collections
      letterList= ['F','I',  'I',  'X',  'O',  'R',  'E']
      toBeFound = ['F', 'I', 'X']
      collections.Counter(letterList)
      a=collections.Counter(letterList) # print(a) does not show order
                                    # but a.keys() has order preserved
      final = [i for i in a.keys() if i in toBeFound]
      if final == toBeFound:
          print("Correct")
      else:
          print("Incorrect")
      

      【讨论】:

        【解决方案5】:

        如果您要检查 letterList 是否按指定顺序包含 toBeFound 的字母并忽略重复的字母,这将是旧“文件匹配”算法的简单变体。您可以像这样在非破坏性函数中实现它:

        def letterMatch(letterList,toBeFound):
            i= 0
            for letter in letterList:
                if letter == toBeFound[i] : i += 1
                elif i > 0 and letter != toBeFound[i-1] : break
                if i == len(toBeFound)    : return True
            return False
        
        letterMatch(['F','I',  'I',  'X',  'O',  'R',  'E'],['F', 'I', 'X'])
        # returns True
        

        另一方面,如果您正在寻找的是测试 letterList 是否具有形成 toBeFound 所需的所有字母(以任何顺序),那么逻辑要简单得多,因为您只需要“检查”这些字母toBeFound 使用 letterList 中的那些:

        def lettermatch(letterList,toBeFound):
            missing = toBeFound.copy()
            for letter in letterList:
                if letter in missing : missing.remove(letter)
            return not missing
        

        【讨论】:

          【解决方案6】:

          根据要求。

          letterList= ['F','I',  'I',  'X',  'O',  'R',  'E']
          toBeFound = ['F', 'I', 'X']
          
          List = []
          for i in toBeFound[:]:
              for l in set(letterList):
                  if l== i:
                      List.append(i)
          if List == toBeFound:
              print("Correct.")
          else:
              print("Incorrect.")
          

          这打印正确。我把 letterList 做成了一套!希望对您有所帮助。

          【讨论】:

          • letterList.remove(l) 在这里没有什么不同。
          • 是的,你绝对正确。他问我是否可以向他展示我所说的制作一套的意思,但他错过了。 @pault。否则,这将返回他正在寻找的答案。
          【解决方案7】:

          一种简单的方法是遍历toBeFound,并在letterList 中查找每个元素。

          letterList= ['F','I',  'I',  'X',  'O',  'R',  'E']
          toBeFound = ['F', 'I', 'X']
          
          found = False
          for x in letterList:
              if x not in toBeFound:
                  found = False
                  break
          
          if found:
             print("Correct.")
          else:
             print("Incorrect.")
          

          【讨论】:

          • 为什么不直接使用 find 的列表理解 = [i for i in toBeFound if i in letterList]
          • 是的,那是另一种方式。虽然打印不正确或正确需要更多逻辑。
          猜你喜欢
          • 1970-01-01
          • 2015-08-28
          • 1970-01-01
          • 2014-07-06
          • 2011-10-22
          • 2020-01-07
          • 1970-01-01
          • 2011-12-02
          相关资源
          最近更新 更多