重复小计列出值,直到没有重复项

时间:2017-05-23 03:52:03

标签: python python-3.x

我在Python中有一个可能包含重复项的数字列表。我需要小计重复值以使用它们,然后解压缩重复项以返回到原始列表并跟踪每个小计中使用的值。我遇到了问题,第一轮小计会导致新的重复,然后必须小计。例如,列表[10,10,20,50,50,75]应该小计为[40,100,75],因为重复的10s的小计导致需要小计的新的重复20s。

我尝试使用以下代码创建重复项的字典并跟踪每个重复项的出现次数,但这不适用于此方案。

while True:
date=int(input("Date?"))
season=""
if date<4:
    season=1
elif date<7:
    season=2
elif date<10:
    season=3
elif date<13:
    season=4
else:
    print("This would not work.")
print(season)

期望的输出:

import collections

def compress_dups(values):
    compressed_indices = []
    for val in set(values): 
        indices = [i for i, x in enumerate(values) if x == val]
        compressed_indices.append(indices)
    return(compressed_indices)  

compress_dict = collections.OrderedDict()
initial_list = [10, 10, 20, 50, 50, 75]
compressed_list = []
g = compress_dups(initial_list)

print(initial_list)

for item in g:  
    compressed_list.append(len(item)*initial_list[min(item)])
    compress_dict[(len(item)*initial_list[min(item)])] = len(item)

print(sorted(compressed_list)) #this is the subtotaled list I'll work with

for k,v in reversed(compress_dict.items()):
    del compressed_list[compressed_list.index(k)]
    for x in xrange(v): 
        compressed_list.append(k/v)

print(sorted(compressed_list)) # this is the list after it's unpacked

4 个答案:

答案 0 :(得分:2)

这是我为完成你的任务而做的一个简单的功能:

def count(lst):
    counter = []
    for e in sorted(lst):
        if e in counter:
            counter.remove(e)
            counter.append(e*2)
        else:
            counter.append(e)
    return counter # or return sorted(counter) if you want it to be sorted

initial_list = [10, 10, 20, 50, 50, 75]
print(count(initial_list)) # prints [40, 100, 75] or [40, 75, 100] if its sorted

second_list = [5, 5, 10, 20, 40, 80]
print(count(second_list)) # prints [160]

third_list = [100, 50, 25, 25, 78]
print(count(third_list)) # prints [78, 200]

说明:此函数创建一个列表,然后使用initial_list进行迭代以检查每个值是否已经存在于新列表中,如果是,则将其从新列表中删除并附加值的两倍。如果不是,只需将值添加到新列表中即可。然后它返回新列表。

答案 1 :(得分:0)

冗长但有效,

def getNextLevel(a):
   b = []
   visited= []
   found = False
   for i in a: 
      if i not in visited:
         c = a.count(i)
         if c>1:
            found = True
         b.append(i*c)
         visited.append(i)
   return [b,found]

if __name__ =='__main__':
   a = [10, 10, 20, 50, 50, 75]
   m = {}
   level = 1
   m[0] = a   
   while True:
      [b,f] = getNextLevel(a)
      if f:
         m[level] = b
         level +=1 
      else:
         break
      a = b

   #print     
   for i in range(level):
      print m[i]

   for i in range(level-2,-1,-1):
      print m[i]

输出,

[10, 10, 20, 50, 50, 75]
[20, 20, 100, 75]
[40, 100, 75] 
[20, 20, 100, 75]
[10, 10, 20, 50, 50, 75]

答案 2 :(得分:0)

您可以使用这样的功能

def sum_dup(l):

for i in range(len(l)-1):
    if l[i] == l[i+1]:
        l[i]+=l[i+1]
        l[i+1] = 0
        l.sort()
l = list(set(l))
l.remove(0)
return(l)

sum_dup(l)

返回

[40, 75, 100]

答案 3 :(得分:0)

  

我需要使用小计重复值来处理它们,然后解压缩重复项以返回原始列表并跟踪每个小计中使用的值。

在Python 3中,可以产生两种结果:

# Python 3
import collections as ct

def compress(initial, saved=None):
    """Yield a compressed list of summed repeated values and a Counter, else compress again."""
    c = ct.Counter(initial)
    if saved is None: saved = c                            # store starting Counter
    if len(initial) == len(set(initial)):
        yield initial
        yield saved
    else:
        compressed = sorted(k*v for k, v in c.items())
        yield from compress(compressed, saved=saved)

lst = [10, 10, 20, 50, 50, 75]
tuple(compress(lst))
# ([40, 75, 100], Counter({10: 2, 20: 1, 50: 2, 75: 1}))

这里我们同时产生压缩列表并开始Counter。注意:术语&#34; compress&#34;不等于itertools.compress。我们现在可以通过迭代Counter

来恢复原始列表
clst, counter = tuple(compress(lst))
rlst = sorted(counter.elements())                          # sorted(k for k, v in counter.items() for _ in range(v))

print("Original list  :", lst)
print("Counter        :", counter)
print("Compressed list:", clst)
print("Recovered list :", rlst)
# Original list  : [10, 10, 20, 50, 50, 75]
# Counter        : Counter({10: 2, 50: 2, 75: 1, 20: 1})
# Compressed list: [40, 75, 100]
# Recovered list : [10, 10, 20, 50, 50, 75]

摘要:此示例使用递归yield from并存储起始计数器以恢复多个元素的原始列表。它适用于多个重复项目,而不仅仅是重复项目。虽然速度慢10倍,但行为并行的@ abccd测试,如果遇到更多重复元素则会有所不同:

lst = [10, 10, 10, 20, 50, 50, 75]
tuple(compress(lst))[0]
# [20, 30, 75, 100]