代码之家  ›  专栏  ›  技术社区  ›  user2727704

基于另一个较短列表的列表排序

  •  4
  • user2727704  · 技术社区  · 6 年前

    sort(key=short_list) :

    long_list = ['y', 'z', 'x', 'c', 'a', 'b']
    short_list = ['b', 'c', 'a']
    long_list.sort(key=short_list.index)
    
    ValueError: 'x' is not in list
    

    long_list 导致 list 维持秩序 short_list 然后是 ?

    ['b', 'c', 'a', 'y', 'z', 'x']
    
    3 回复  |  直到 6 年前
        1
  •  3
  •   dawg    6 年前

    你可以用 in 要检测元素是否在short\列表中,请使用三元组返回基于该元素的元组:

    >>> long_list = ['y', 'z', 'x', 'c', 'a', 'b']
    >>> short_list = ['b', 'c', 'a']
    >>> sorted(long_list, key=lambda e: (short_list.index(e),e) if e in short_list  else (len(short_list),e))
    ['b', 'c', 'a', 'x', 'y', 'z']
    

    (index_of_the_element, element) 属于 (len(short_list), element) 为了实现这种改变。

    >>> sorted(long_list, key=lambda e: (short_list.index(e),e) if e in short_list  else (len(short_list),))
    ['b', 'c', 'a', 'y', 'z', 'x']
    
        2
  •  5
  •   Florian Weimer    6 年前

    def position(value):
        try:
            return short_list.index(value)
        except ValueError:
            return len(short_list)
    
    long_list.sort(key=position)
    

    Sorting is guaranteed to be stable ,所以使用 len(short_list)

        3
  •  2
  •   mg.    6 年前

    我会先在短名单中搜索,必要时在长名单中搜索:

    >>> def index(list1, list2):
    ...  def inner(value):
    ...   try:
    ...    return list1.index(value)
    ...   except ValueError:
    ...    return list2.index(value)
    ... 
    >>> long_list = ['x', 'y', 'z', 'a', 'b', 'c']
    >>> short_list = ['a', 'b', 'c']
    >>> long_list.sort(key=index(short_list, long_list))
    >>> long_list
    ['a', 'b', 'c', 'x', 'y', 'z']
    

    pointed out ,此解决方案并不总是有效。将两种解决方案结合起来:

    >>> def index(list1, list2):
    ...  def inner(value, l=len(list1)):
    ...   try:
    ...    return list1.index(value)
    ...   except ValueError:
    ...    return l
    ...  return inner
    ... 
    >>> long_list = ['x', 'y', 'z', 'a', 'b', 'c']
    >>> short_list = ['a', 'b', 'c', 'y']
    >>> sorted(long_list, key=index(short_list, long_list))
    ['a', 'b', 'c', 'y', 'x', 'z']
    >>>