【问题标题】:Python: split list into indices based on consecutive identical valuesPython:根据连续的相同值将列表拆分为索引
【发布时间】:2017-01-19 21:45:40
【问题描述】:

如果您能建议我如何编写脚本以按值的数量拆分列表,我的意思是:

my_list =[11,11,11,11,12,12,15,15,15,15,15,15,20,20,20] 

并且有 11-4,12-2,15-6,20-3 项。 所以在下一个示例范围列表中(0:100) 我必须分成 4,2,6,3 部分 所以我为拆分列表计算了相同的值和函数,但它不适用于列表:

 div=Counter(my_list).values() ##counts same values in the list

 def chunk(it, size):
    it = iter(it)
    return iter(lambda: tuple(islice(it, size)), ())

我需要什么:

Out: ([0,1,2,3],[4,5],[6,7,8,9,10,11], etc...] 

【问题讨论】:

  • 结帐itertools.groupby()enumerate()
  • def get_chunks(li, n): ; for i in range(0, len(li), n): ; yield li[i: i + n] 此切片将li 列出到大小为n 的块(最后一个块将具有<=n 值)。看看如何修改它以满足您的需求。
  • @DeepSpace 主要问题是什么,我不能使用大小(n)这样的列表。 l1=[3,2,4,] #零件尺寸`。我需要拆分 l2=[10,15,9,2,0,5,6,3,9]。结果应该是这样的: res= [[10,15,9],[9,2],[0,6,3,9]]

标签: python list split


【解决方案1】:

您可以使用enumerateitertools.groupbyoperator.itemgetter

In [45]: import itertools

In [46]: import operator

In [47]: [[e[0] for e in d[1]] for d in itertools.groupby(enumerate(my_list), key=operator.itemgetter(1))]
Out[47]: [[0, 1, 2, 3], [4, 5], [6, 7, 8, 9, 10, 11], [12, 13, 14]]

它的作用如下:

  1. 首先枚举项目。

  2. 它使用每个枚举元组中的第二项(原始值)对它们进行分组。

  3. 在每个组的结果列表中,它使用每个元组中的第一项(枚举)

【讨论】:

  • 效果很好,但如果我已经得到了我应该拆分的列表?我的意思是:my_list(这里我得到零件的数量)和第二个列表,例如 my_data = [10,9,8,7,6,100,45,12,4] 拆分。其实我是初学者,很抱歉我的愚蠢问题
  • 我很抱歉。现在不在电脑前,以后可以看看这个。
  • =) 别担心=)慢慢来
【解决方案2】:

Python 3 中的解决方案,如果你只使用counter

from collections import Counter
my_list =[11,11,11,11,12,12,15,15,15,15,15,15,20,20,20] 
count = Counter(my_list)
div= list(count.keys())         # take only keys
div.sort()
l = []
num = 0
for i in div:
    t = []
    for j in range(count[i]):   # loop number of times it occurs in the list
        t.append(num)
        num+=1
    l.append(t)
print(l)

输出:

[[0, 1, 2, 3], [4, 5], [6, 7, 8, 9, 10, 11], [12, 13, 14]]

使用set 的替代解决方案:

my_list =[11,11,11,11,12,12,15,15,15,15,15,15,20,20,20] 
val = set(my_list)                     # filter only unique elements
ans = []
num = 0
for i in val:
    temp = []
    for j in range(my_list.count(i)):   # loop till number of occurrence of each unique element
        temp.append(num)
        num+=1
    ans.append(temp)
print(ans)

编辑: 根据@Protoss Reed 在 cmets 中提到的为获得所需输出所做的必要更改

my_list =[11,11,11,11,12,12,15,15,15,15,15,15,20,20,20] 
val = list(set(my_list))                     # filter only unique elements
val.sort()                                   # because set is not sorted by default
ans = []
index = 0
l2 = [54,21,12,45,78,41,235,7,10,4,1,1,897,5,79]
for i in val:
    temp = []
    for j in range(my_list.count(i)):   # loop till number of occurrence of each unique element
        temp.append(l2[index])
        index+=1
    ans.append(temp)
print(ans)

输出:

[[54, 21, 12, 45], [78, 41], [235, 7, 10, 4, 1, 1], [897, 5, 79]]

这里我必须将set 转换为list,因为set 没有排序,我认为剩余的部分是不言自明的。

另一种解决方案如果输入并不总是排序(使用OrderedDict):

from collections import OrderedDict
v = OrderedDict({})
my_list=[12,12,11,11,11,11,20,20,20,15,15,15,15,15,15]
l2 = [54,21,12,45,78,41,235,7,10,4,1,1,897,5,79]
for i in my_list:                # maintain count in dict
    if i in v:
        v[i]+=1
    else:
        v[i]=1
ans =[]
index = 0
for key,values in v.items():
    temp = []
    for j in range(values):
        temp.append(l2[index])
        index+=1
    ans.append(temp)
print(ans)

输出:

[[54, 21], [12, 45, 78, 41], [235, 7, 10], [4, 1, 1, 897, 5, 79]]

这里我使用OrderedDict 来维护输入序列的顺序,在set 的情况下是随机的(不可预测的)。

虽然我更喜欢 @Ami Tavory 的解决方案,它更符合 Python 风格。

[额外工作:如果有人可以将此解决方案转换为list comprehension,那将是非常棒的,因为我尝试过但无法将其转换为list comprehension,如果您成功,请将其发布在 cmets 中,这将有助于我理解]

【讨论】:

  • 感谢您的帮助!代码运行良好,但是我确实需要 my_list 零件数量(4,2,6,3)divset 是否很好,但主要问题是什么我必须拆分另一个列表例如 @ 987654341@ 并得到如下结果:res= [[ 54,21,12,45],[78,41],[235,7,10,4,1,1],[897,5,79]
  • @Protoss Reed 我对答案进行了更改。希望这会有所帮助。
  • 嘿!完美!谢谢!你做得很好!但是如果你不介意你能解释一下这个排序列表是否重要吗?因为我只需要它的零件数量。但有特殊顺序。 My_list 并不总是看起来像(排序的)它可能是一个随机数。 my_list=[23,23,23,1,1,1,1,44,6542,6542..etc]
  • @Protoss Reed 哦,我认为它总是排序的。一件事重复数字总是连续的或随机的,比如[1,1,22,5,22,1]?
  • 它们是随机的
猜你喜欢
  • 1970-01-01
  • 2013-09-05
  • 2019-01-30
  • 2020-05-02
  • 2017-08-06
  • 1970-01-01
  • 2019-01-04
  • 2018-09-24
相关资源
最近更新 更多