【问题标题】:How to sort integers in a list of lists but via skipping a particular index of each list?如何通过跳过每个列表的特定索引对列表列表中的整数进行排序?
【发布时间】:2020-04-19 22:26:54
【问题描述】:

我有一个包含 3 个整数的列表,如下所示:

myList = [[1,2,3],[2,4,3],[2,1,3],[3,2,4],[5,4,3],[4,3,2],[5,4,3], [3,4,2]]

如果列表在 myList 中有对称,我想删除它。例如。 [1,2,3][3,2,1] 是对称的,[1,2,3][3,2,1] 可以保留在新列表中,但不能同时保留。

我尝试排序以摆脱对称列表

myList = [[1,2,3],[2,4,3],[2,1,3],[3,2,4],[5,4,3],[4,3,2],[5,4,3], [3,4,2]]
result = set()

for elem in myList: 
    result.add(tuple(sorted(elem)))

result = list(result)
print(result)

代码结果为:

[(3, 4, 5), (2, 3, 4), (1, 2, 3)]

虽然我确实摆脱了对称列表,但我希望将每个数字的位置保持在中间不变,并且仅通过考虑它们的第一个和第三个整数来按递增/递减顺序对每个列表进行排序.

例如。 [2,4,3],[3,2,4],[3,4,2] 应该排序为 -> [2,4,3],[3,2,4],[2,4,3] 然后我可以摆脱相同的 -> [2,4,3],[3,2,4]

您能否建议我一种方法来对 myList 中的列表中的整数进行排序,但通过跳过每个列表的中间值,如下所示,以便我可以消除对称列表?

【问题讨论】:

  • [3, 1, 2] 是否也与[1, 2, 3] 对称?
  • 不,不是。我所说的对称是指 [x,y,z] 和 [z,y,x]。
  • 另外,根据选择标准,原始列表中只能保留一个元素

标签: python list sorting


【解决方案1】:

来自

[[1,2,3],[3,2,1],[3,1,2],[2,1,3],[1,3,2],[2,3,1]]

我们坚持

[[1,2,3],        [3,1,2],        [1,3,2]]

因为中间元素是固定的,而被移除的元素中的第 1/3 个元素是相等的。

我们通过创建包含中间元素和所有数字集合的元组来实现这一点 - 我们保留每个中的第一个,我们丢弃其他的 - 所有这些都完全不重新排序原始元素:

myList = [[1,2,3],[2,4,3],[2,1,3],[3,2,4],[5,4,3],[4,3,2],[5,4,3], [3,4,2]]

# create a set of sets to keep
mySets = set((p[1],frozenset(p)) for p in myList)

rv = []

# go through your list
for nums in myList:
    # create a set from the current item in your list
    fs = (nums[1], frozenset(nums))
    # if we want to keep it, do so
    if fs in mySets:
        rv.append(nums)
        # and remove it from the to be kept list
        mySets.remove(fs)
    # if empty, we are done
    if not mySets:
        break 
print(rv)           

输出:

[[1, 2, 3], [2, 4, 3], [2, 1, 3], [3, 2, 4], [5, 4, 3], [4, 3, 2]]   

【讨论】:

    【解决方案2】:
    # Removes symmetry.
    removed_symmetry = list(filter(lambda obj: tuple(obj) not in [tuple(x) for x in [i for i in myList if i is not obj]], myList))
    
    # Sorts based on left and right value.
    middle_unchanged_sort = [[x, y, z] if x < z else [z, y, x] for x, y, z in myList]
    

    不确定我是否完全理解您的要求,但以上两个将对myList 提供单独的功能。

    【讨论】:

      【解决方案3】:

      这应该可行:

      myList = [[1,2,3],[2,4,3],[2,1,3],[3,2,4],[5,4,3],[4,3,2],[5,4,3], [3,4,2]]
      result = set()
      for elem in myList:
          # Check if reversed tuple is in the set 
          if tuple(reversed(elem)) not in result:
              # Add it to the set if not
              result.add(tuple(elem))
      
      # Map the tuple set to lists of list
      result = list(map(list, result))
      
      print(result)
      
      

      给出结果:

      [[2, 4, 3], [4, 3, 2], [1, 2, 3], [5, 4, 3], [3, 2, 4], [2, 1, 3]]
      

      【讨论】:

        【解决方案4】:

        您想要的是来自myList 的唯一listsset。请参阅最后一节标题了解您要求的排序方式。

        一组唯一元组

        如果以一组元组的形式获得最终结果有效,那么您可以如下所示。

        set([tuple(sorted(e)) for e in myList])
        # Or using map
        set(map(lambda x: tuple(sorted(x)), myList))
        

        输出

        {(1, 2, 3), (2, 3, 4), (3, 4, 5)}
        

        唯一列表列表

        如果您必须将最终结果作为唯一列表的列表,那么您可以试试这个。

        [list(ee) for ee in set([tuple(sorted(e)) for e in myList])]
        # Or using map
        list(map(list, set([tuple(sorted(e)) for e in myList])))
        

        输出

        [[3, 4, 5], [2, 3, 4], [1, 2, 3]]
        

        提取非重复/非镜像列表

        您也可以使用pandas 库来执行此操作。

        import numpy as np
        import pandas as pd
        # use pandas.DataFrame to sort by 
        # first and third values in each row
        df = pd.DataFrame(np.array(myList), columns=['A', 'B', 'C'])
        df['D'] = df.apply(lambda row: '{}-{}-{}'.format(row.A+row.C, row.B, row.C+row.A), axis=1)
        
        df = (df
                .sort_values(['D', 'A', 'C'], ascending=True, inplace=False)
                .drop_duplicates(subset=['D'], keep='first', inplace=False, ignore_index=False)
                .drop(columns=['D'], inplace=False)
            )
        #print(df)
        
        # make list of lists sorted by 
        # first and third values in each list
        # And drop the duplicates (mirrored)
        [list(e) for e in df.to_numpy()]
        # Or
        list(map(list, df.to_numpy()))
        

        输出

        [[1, 2, 3], [2, 1, 3], [2, 4, 3], [4, 3, 2], [3, 2, 4], [5, 4, 3]]
        

        如果您希望以与原始myList 相同的顺序得到答案,您可以执行以下操作:

        # after running what was done previously to df
        [list(e) for e in df.sort_index().to_numpy()]
        # Or
        list(map(list, df.sort_index().to_numpy()))
        

        输出

        [[1, 2, 3], [2, 4, 3], [2, 1, 3], [3, 2, 4], [5, 4, 3], [4, 3, 2]]
        

        【讨论】:

          猜你喜欢
          • 2011-05-09
          • 2021-07-04
          • 1970-01-01
          • 2016-09-10
          • 2015-07-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多