【问题标题】:write a function that receives a list of strings and return list of lists编写一个接收字符串列表并返回列表列表的函数
【发布时间】:2021-01-21 16:14:07
【问题描述】:

对于这个特定问题,我找不到任何类似的解决方案。

编写一个接收字符串列表并返回列表列表的函数,一组列表中的每个项目与该列表中的其他项目具有相同的字母(不同的顺序)。

(abc, acb, aab, aba) --> ((abc, acb), (aab, aba))

这是我到目前为止的代码,但它不太正确, 首先它在 O(n^2) 中运行,我需要 O(n) 中的解决方案 其次,如果有超过 2 个相似之处,则整个结果是不正确的。

def ex1(str_list: list = ()) -> list:
    result = []
        items = []
        for item in str_list:
            items.append(''.join(sorted(item)))
        for i in range(len(items)):
            for j in range(i):
                if items[i] == items[j]:
                    result.append([str_list[j], str_list[i]])

        return result

我寻求的解决方案是使用字典,时间复杂度为 O(n) 例如

输入:['abc', 'acb', 'aab', 'aba', 'bac']

输出:[['abc', 'acb', 'bac'], ['aab', 'aba']]

【问题讨论】:

    标签: python string list performance nested-lists


    【解决方案1】:

    使用分组习语并使用 sorted 字符串作为键:

    >>> import collections
    >>> data = ['abc', 'acb', 'aab', 'aba', 'bac']
    >>> def group_by_letters(strings):
    ...     grouper = collections.defaultdict(list)
    ...     for string in strings:
    ...         grouper[tuple(sorted(string))].append(string)
    ...     return list(grouper.values())
    ...
    >>> group_by_letters(data)
    [['abc', 'acb', 'bac'], ['aab', 'aba']]
    

    【讨论】:

      【解决方案2】:

      这是一个简单的工作示例:

      from collections import defaultdict
      from typing import List, Tuple
      
      
      def string_key(string: str) -> Tuple[str, ...]:
          """Returns a key which is unique on the characters in the string (ignoring ordering)."""
          return tuple(sorted(string))
      
      
      def group_by_chars(data: List[str]) -> List[List[str]]:
          """Group strings by the characters they contain, regardless of order."""
          result = defaultdict(list)
          for value in data:
              key = string_key(value)
              result[key].append(value)
          return list(result.values())
      
      
      assert group_by_chars(["abc", "acb", "aab", "aba"]) == [["abc", "acb"], ["aab", "aba"]]
      

      诀窍是定义一个函数,将属于同一组的值映射到同一个键,然后根据该键函数的输出将每个值放入一个桶中。

      另一种方法是使用sorteditertools.groupby

      from itertools import groupby
      
      from typing import List, Tuple
      
      
      def string_key(string: str) -> Tuple[str, ...]:
          """Returns a key which is unique on the characters in the string (ignoring ordering)."""
          return tuple(sorted(string))
      
      
      def alternate_group_by_chars(data: List[str]) -> List[List[str]]:
          result = []
          for _key, group in groupby(sorted(data, key=string_key), string_key):
              result.append(list(group))
          return result
      

      但是这会以不同的顺序返回结果(由于必要的sorted)并且认为它的可读性较差。

      【讨论】:

      • 后者也不是 O(N) 而是 O(N logN)
      • 非常感谢!!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-20
      • 2020-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多