Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 根据第一个常用项将子列表排序为新的子列表_Python_List_Sorting - Fatal编程技术网

Python 根据第一个常用项将子列表排序为新的子列表

Python 根据第一个常用项将子列表排序为新的子列表,python,list,sorting,Python,List,Sorting,我有大量两个成员的子列表,它们是名为mylist的列表的成员: mylist = [['AB001', 22100], ['AB001', 32935], ['XC013', 99834], ['VD126', 18884], ['AB001', 34439], ['XC013', 86701]] 我想根据子列表是否包含与第一项相同的字符串,将mylist排序到新的子列表中。例如,这就是我希望代

我有大量两个成员的子列表,它们是名为
mylist
的列表的成员:

mylist = [['AB001', 22100],
          ['AB001', 32935],
          ['XC013', 99834],
          ['VD126', 18884],
          ['AB001', 34439],
          ['XC013', 86701]]
我想根据子列表是否包含与第一项相同的字符串,将
mylist
排序到新的子列表中。例如,这就是我希望代码输出的内容:

newlist = [['AB001', 22100], ['AB001', 32935], ['AB001', 34439]],
          [['XC013', 99834], ['XC013', 86701]],
          [['VD126', 18884]]
下面是我如何编写代码的:

mylist = sorted(mylist)
newlist = []
for sublist in mylist:
    id = sublist[0]
if id == next.id:
    newlist.append(id)
print newlist

我还试图了解
itertools.groupby()
是否是解决此问题的正确工具。有人能帮我解决这个问题吗

你说得对,这是一份适合以下人员的工作:

这将为您提供一个列表列表,按子列表中的第一项分组

[[['AB001', 4439], ['AB001', 22100], ['AB001', 32935]], 
 [['VD126', 18884]], 
 [['XC013', 86701], ['XC013', 99834]]]
itertools.groupby
解决方案将产生O(n log n)成本,因为必须首先对输入进行排序。您可以使用列表的
defaultdict
来保证O(n)解决方案:

from collections import defaultdict

dd = defaultdict(list)
for item in mylist:
    dd[item[0]].append(item)

res = list(dd.values())

print(res)

[[['AB001', 22100], ['AB001', 32935], ['AB001', 34439]],
 [['XC013', 99834], ['XC013', 86701]],
 [['VD126', 18884]]]
不导入任何包:
  • 构建一个字典,然后将值添加到列表中
    • 用于确定某个键是否存在,如果该键不存在,则返回某个指定值,
      None
    • 默认为
      None
      ,因此此方法不会引发错误。
      • 如果
        None
        是字典中的值,则更改
        .get
        返回的默认值。
        • test.get(t[0],'something here')
  • 因为:基于公共首项的子列表。
    • 添加索引0作为
      ,然后添加
      列表
      t
      ,作为
      dict
test=dict()
对于mylist中的t:
如果test.get(t[0])==无:
测试[t[0]]=[t]
其他:
测试[t[0]]。追加(t)
final=列表(test.values())
#在中打印最终结果
[AB001',22100],[AB001',32935],[AB001',34439],
[XC013',99834],[XC013',86701],
[VD126',18884]]

解决此问题有多种选择:

def regroup_by_di(items, key=None):
    result = {}
    callable_key = callable(key)
    for item in items:
        key_value = key(item) if callable_key else item
        if key_value not in result:
            result[key_value] = []
        result[key_value].append(item)
    return result
这些可分为两类:

  • 循环输入,创建一个类似于dict的结构(
    按di()重新分组()
    按dd()重新分组()
    按sd()重新分组()
  • 对输入进行排序,然后使用一个类似的函数(例如)(
    regroupbyuit()
    regroupbyugb()
  • 第一类方法具有
    O(n)
    计算复杂度,而第二类方法具有
    O(n logn)

    所有建议的方法都需要指定一个
    。 对于OP的问题,
    操作符.itemgetter(0)
    lambda x:x[0]
    可以工作。此外,要获得OP所需的结果,只能获得
    列表(dict.values())
    ,例如:

    from operator import itemgetter
    
    
    mylist = [['AB001', 22100],
              ['AB001', 32935],
              ['XC013', 99834],
              ['VD126', 18884],
              ['AB001', 4439],
              ['XC013', 86701]]
    
    
    print(list(regroup_by_di(mylist, key=itemgetter(0)).values()))
    # [[['AB001', 22100], ['AB001', 32935], ['AB001', 4439]], [['XC013', 99834], ['XC013', 86701]], [['VD126', 18884]]]
    

    所有基于
    dict
    的(一级)解决方案的计时速度更快,而所有基于
    groupby
    的(二级)解决方案的计时速度较慢。 在基于dict的
    解决方案中,它们的性能将略微取决于“碰撞率”,这与新项目创建新对象的次数成正比。
    对于较高的碰撞率,
    regroup\u by_di()
    可能是最快的,而对于较低的碰撞率,
    regroup\u by_dd()
    可能是最快的

    基准如下:

    • 0.1%碰撞率(每组约1000个元件)

    • 10%碰撞率(每组约10个元件)

    • 50%碰撞率(每组约2个元件)

    • 100%碰撞率(每组约1个元件)


    (更多详细信息可用。)

    若要保存导入,您是否可以使用lambda而不是itemgetter?是的,但速度较慢,这就是
    itemgetter
    的作用。实际上,您必须按分组所依据的键进行排序,因此,
    sorted(mylist)
    应替换为
    sorted(mylist,key=itemgetter(0)
    @norok2这取决于你是否关心组中值的顺序。如果你不关心,你是对的,你可以再次使用
    itemgetter
    。但是这个细节对答案的要点并不重要;重要的部分是
    groupby
    itemgetter
    。在这种情况下,de>错误排序工作正常。这不是赌注组中值的顺序,而是组本身。
    sorted(mylist)
    在这里工作正常,因为
    sorted(mylist,key=itemgetter(0))
    将导致相同的分组(对组中值的顺序进行模化)在这种情况下,但它通常是不正确的,例如
    l=(1,2,3,4)
    def(x):返回x%2
    [在groupby中k,v的列表(v)(排序的(l),key=f)]
    ->
    [[1],[2],[3],[4]
    错误;
    [list(v)对于k,v在groupby中(排序的(l,key=f),key=f)]
    import collections def regroup_by_dd(items, key=None): result = collections.defaultdict(list) callable_key = callable(key) for item in items: result[key(item) if callable_key else item].append(item) return dict(result) # to be in line with other solutions
    def regroup_by_sd(items, key=None):
        result = {}
        callable_key = callable(key)
        for item in items:
            key_value = key(item) if callable_key else item
            result.setdefault(key_value, []).append(item)
        return result
    
    import itertools
    
    
    def regroup_by_it(items, key=None):
        seq = sorted(items, key=key)
        result = {
            key_value: list(group)
            for key_value, group in itertools.groupby(seq, key)}
        return result
    
    def group_by(
            seq,
            key=None):
        items = iter(seq)
        try:
            item = next(items)
        except StopIteration:
            return
        else:
            callable_key = callable(key)
            last = key(item) if callable_key else item
            i = j = 0
            for i, item in enumerate(items, 1):
                current = key(item) if callable_key else item
                if last != current:
                    yield last, seq[j:i]
                    last = current
                    j = i
            if i >= j:
                yield last, seq[j:i + 1]
    
    
    def regroup_by_gb(items, key=None):
        return dict(group_by(sorted(items, key=key), key))
    
    from operator import itemgetter
    
    
    mylist = [['AB001', 22100],
              ['AB001', 32935],
              ['XC013', 99834],
              ['VD126', 18884],
              ['AB001', 4439],
              ['XC013', 86701]]
    
    
    print(list(regroup_by_di(mylist, key=itemgetter(0)).values()))
    # [[['AB001', 22100], ['AB001', 32935], ['AB001', 4439]], [['XC013', 99834], ['XC013', 86701]], [['VD126', 18884]]]