nodes: 0, module; 1, function_definition; 2, function_name:dedupe_and_sort; 3, parameters; 4, block; 5, identifier:sequence; 6, default_parameter; 7, default_parameter; 8, expression_statement; 9, expression_statement; 10, expression_statement; 11, comment:# Add items that should be sorted first.; 12, expression_statement; 13, comment:# Add remaining items in their current order, ignoring duplicates and items; 14, comment:# that should be sorted last.; 15, for_statement; 16, comment:# Add items that should be sorted last.; 17, expression_statement; 18, comment:# Return a sequence of the same type as given.; 19, return_statement; 20, identifier:first; 21, None; 22, identifier:last; 23, None; 24, comment:"""
      De-dupe and partially sort a sequence.
  
      The `first` argument should contain all the items that might appear in
      `sequence` and for which the order (relative to each other) is important.
  
      The `last` argument is the same, but matching items will be placed at the
      end of the sequence.
  
      For example, `INSTALLED_APPS` and `MIDDLEWARE_CLASSES` settings.
  
      Items from `first` will only be included if they also appear in `sequence`.
  
      Items from `sequence` that don't appear in `first` will come
      after any that do, and retain their existing order.
  
      Returns a sequence of the same type as given.
      """; 25, assignment; 26, assignment; 27, assignment; 28, identifier:item; 29, identifier:sequence; 30, block; 31, call; 32, call; 33, identifier:first; 34, boolean_operator; 35, identifier:last; 36, boolean_operator; 37, identifier:new_sequence; 38, list_comprehension; 39, if_statement; 40, attribute; 41, argument_list; 42, call; 43, argument_list; 44, identifier:first; 45, list; 46, identifier:last; 47, list; 48, identifier:i; 49, for_in_clause; 50, if_clause; 51, boolean_operator; 52, block; 53, identifier:new_sequence; 54, identifier:extend; 55, list_comprehension; 56, identifier:type; 57, argument_list; 58, identifier:new_sequence; 59, identifier:i; 60, identifier:first; 61, comparison_operator:i in sequence; 62, comparison_operator:item not in new_sequence; 63, comparison_operator:item not in last; 64, expression_statement; 65, identifier:i; 66, for_in_clause; 67, if_clause; 68, identifier:sequence; 69, identifier:i; 70, identifier:sequence; 71, identifier:item; 72, identifier:new_sequence; 73, identifier:item; 74, identifier:last; 75, call; 76, identifier:i; 77, identifier:last; 78, comparison_operator:i in sequence; 79, attribute; 80, argument_list; 81, identifier:i; 82, identifier:sequence; 83, identifier:new_sequence; 84, identifier:append; 85, identifier:item
code: def dedupe_and_sort(sequence, first=None, last=None):
      """
      De-dupe and partially sort a sequence.
  
      The `first` argument should contain all the items that might appear in
      `sequence` and for which the order (relative to each other) is important.
  
      The `last` argument is the same, but matching items will be placed at the
      end of the sequence.
  
      For example, `INSTALLED_APPS` and `MIDDLEWARE_CLASSES` settings.
  
      Items from `first` will only be included if they also appear in `sequence`.
  
      Items from `sequence` that don't appear in `first` will come
      after any that do, and retain their existing order.
  
      Returns a sequence of the same type as given.
      """
      first = first or []
      last = last or []
      # Add items that should be sorted first.
      new_sequence = [i for i in first if i in sequence]
      # Add remaining items in their current order, ignoring duplicates and items
      # that should be sorted last.
      for item in sequence:
          if item not in new_sequence and item not in last:
              new_sequence.append(item)
      # Add items that should be sorted last.
      new_sequence.extend([i for i in last if i in sequence])
      # Return a sequence of the same type as given.
      return type(sequence)(new_sequence)