唯一编号的代码顺序组合

时间:2018-01-20 17:53:26

标签: python

您好我正在处理一段代码,它接收一个数字数组并返回一组数组。例如:

A = [5, 6, 7, 8]
B = [1, 2, 6, 7]
C = [3, 4, 6, 7, 8, 9]

当我将这些数组逐个传入函数时,我得到以下结果:

ResultA = [[5, 6, 7, 8]]
ResultB = [[1, 2], [6, 7]]
ResultC = [[3, 4], [6, 7, 8, 9]]

我已经写下了一份能够做到这一点的非常粗略的代码,但我确信它没有得到优化。以下是我的代码:

def to_unique_numeric_combinations(number_collection: list):
if not isinstance(number_collection, list):
    raise TypeError("The input must be a list of numbers")
result = []
number_dict = {}
for i in number_collection:
    number_dict[i] = 0
for i in number_collection:
    if number_dict[i] < 1:
        res = [i]
        for j in range(i + 1, max(number_collection) + 1):
            if j in number_dict and number_dict[j] < 1:
                number_dict[j] = 1
                res.append(j)
            else:
                break
        if len(number_collection) > 0:
            result.append(res)
return result

我正在研究使用while循环的另一种解决方案,这种方式更快。以下是该代码:

def with_while_loop(x):
result = []
i = 0
res = []
while i <= len(x) - 1:
    j = i + 1
    res.append(x[i])
    if i == len(x) - 1:
        result.append(res)
        i += 1
    elif x[i] + 1 == x[j]:
        i += 1
    else:
        result.append(res)
        res = []
        i += 1
return result

我的问题是,有什么方法比它更好,更优化吗?

3 个答案:

答案 0 :(得分:2)

我不确定性能,但你可以这样做:

def breaker(collection, sort=False):
    if sort:
        collection.sort()

    res = []
    aux = [collection[0]]

    for num in collection[1:]:
        if aux[-1] + 1  == num:
            aux.append(num)
        else:
            res.append(aux)
            aux = [num]

    if aux:
        res.append(aux)

    return res

样本用法:

>>> breaker([1, 2, 5, 7, 8])
[[1, 2], [5], [7, 8]]
>>> breaker([5, 2, 1, 8, 7], sort=True)
[[1, 2], [5], [7, 8]]

希望它有所帮助。 =)

答案 1 :(得分:1)

使用Pandas可以:

import pandas as pd

def group_consequent_elements(list_of_ints):
    '''Returns a nested list for the numerically consequent elements'''
    df = pd.DataFrame({"vals": list_of_ints})
    df["groups"] = ((df['vals'].diff() != 1).cumsum())
    return df.groupby("groups")["vals"].apply(list).tolist()

# Results 
group_consequent_elements(A) # [[5, 6, 7, 8]]
group_consequent_elements(B) # [[1, 2], [6, 7]]
group_consequent_elements(C) # [[3, 4], [6, 7, 8, 9]]

为了进一步阐明逻辑,以下是印刷的中间步骤:

df = pd.DataFrame({"vals": C}) 
df['diff'] = df['vals'].diff()
df['not_consequent'] = df['diff'] != 1
df["groups"] = df['not_consequent'].cumsum()           

#    vals  diff  not_consequent  groups
# 0     3   NaN            True       1
# 1     4   1.0           False       1
# 2     6   2.0            True       2
# 3     7   1.0           False       2
# 4     8   1.0           False       2
# 5     9   1.0           False       2

答案 2 :(得分:0)

你可以试试这个:

C = [3, 4, 6, 7, 8, 9]
newList=[]
indices=[C[c]-C[c-1] for c,e in enumerate(sorted(C)) if c!=0]
loopvar=0
for c,e in enumerate(indices):
    if e!=1 or c==len(C)-2:
        newList.append(C[loopvar:c+1])
        loopvar=c