简体   繁体   English

检查python列表中的序列

[英]Checking for a sequence in a python list

I have a list [T20, T5, T10, T1, T2, T8, T16, T17, T9, T4, T12, T13, T18] 我有一个清单[T20,T5,T10,T1,T2,T8,T16,T17,T9,T4,T12,T13,T18]

I have stripped out the T's, coverted to integer type and sorted the list to get this: 我已经删除了T,转换为整数类型并对列表进行排序以获得:

sorted_ids=[1, 2, 4, 5, 8, 9, 10, 12, 13, 16, 17, 18, 20] sorted_ids = [1,2,4,5,8,9,10,12,13,16,17,18,20]

I'm looping over the list and checking if the next number to current number is in numerical sequence. 我循环遍历列表并检查当前数字的下一个数字是否按数字顺序排列。 If not I want to insert a "V" in its position. 如果不是,我想在其位置插入“V”

So eventually the list should look like: [1, 2, V, 4, 5, V, V, 8, 9, 10, V, 12, 13, V, V, 16, 17, 18, V, 20] 因此最终列表应如下所示: [1,2,V,4,5,V,V,8,9,10,V,12,13,V,V,16,17,18,V,20]

However, I'm not able to insert the exact no of V's at the right positions. 但是,我无法在正确的位置插入精确的V值

def arrange_tickets(tickets_list):

    ids=[]
    for item in tickets_list:
        new_str=item.strip("T")
        ids.append(int(new_str))
    sorted_ids = sorted(ids)
    temp_ids = []
    print("Sorted: ",sorted_ids)
    #size = len(sorted_ids)
    for i in range(len(sorted_ids)-1):
        temp_ids.append(sorted_ids[i])

        if sorted_ids[i]+1 != sorted_ids[i+1] :
            temp_ids.insert(i+1,"V")
    print(temp_ids)
    #print(sorted_ids)


tickets_list = ['T20', 'T5', 'T10', 'T1', 'T2', 'T8', 'T16', 'T17', 'T9', 'T4', 'T12', 'T13', 'T18']
print("Ticket ids of all the available students :")
print(tickets_list)
result=arrange_tickets(tickets_list)

Actual Result: [1, 2, 'V', 4, 'V', 5, 8, 'V', 9, 'V', 10, 12, 'V', 13, 16, 17, 18] 实际结果: [1,2,'V',4,'V',5,8,'V',9,'V',10,12,'V',13,16,17,18]

Expected Result: [T1, T2, V, T4, T5, V, V, T8, T9, T10, V, T12, T13, V, V, T16, T17, T18, V, T20] 预期结果: [T1,T2,V,T4,T5,V,V,T8,T9,T10,V,T12,T13,V,V,T16,T17,T18,V,T20]

Here is a solution: 这是一个解决方案:

sorted_ids=[1, 2, 4, 5, 8, 9, 10, 12, 13, 16, 17, 18, 20]

def arrange(inList):
    newList = []
    newList.append('T'+str(inList[0]))
    for i in range(1,len(inList)):
        diff = inList[i] - inList[i-1]
        if diff > 1:
            for d in range(diff-1):
                newList.append('V')
            newList.append('T'+str(inList[i]))
        else:
            newList.append('T'+str(inList[i]))
    return newList

print(arrange(sorted_ids))

Output: 输出:

['T1', 'T2', 'V', 'T4', 'T5', 'V', 'V', 'T8', 'T9', 'T10', 'V', 'T12', 'T13', 'V', 'V', 'T16', 'T17', 'T18', 'V', 'T20']

Here's another solution worth considering: 这是另一个值得考虑的解决方案:

sorted_ids=[1, 2, 4, 5, 8, 9, 10, 12, 13, 16, 17, 18, 20]

for i in range(min(sorted_ids), max(sorted_ids)): 
     if sorted_ids[i] != i + 1: 
         sorted_ids.insert(i, 'V')

final_list = [ "T" + str(x) if isinstance(x, int) else x for x in sorted_ids]

result: 结果:

['T1', 'T2', 'V', 'T4', 'T5', 'V', 'V', 'T8', 'T9', 'T10', 'V', 'T12', 'T13', 'V', 'V', 'T16', 'T17', 'T18', 'V', 'T20']

Here is a list comprehension which gets you what you want: 这是一个列表理解,它可以让你得到你想要的:

sorted_ids=[1, 2, 4, 5, 8, 9, 10, 12, 13, 16, 17, 18, 20]
a = sorted_ids[0]
b = sorted_ids[-1]
nums = set(sorted_ids)
expected = ["T" + str(i) if i in nums else 'V' for i in range(a,b+1)]
print(expected)

Output: 输出:

['T1', 'T2', 'V', 'T4', 'T5', 'V', 'V', 'T8', 'T9', 'T10', 'V', 'T12', 'T13', 'V', 'V', 'T16', 'T17', 'T18', 'V', 'T20']
temp_ids.insert(i+1,"V") 

This is the troublesome statement. 这是一个麻烦的陈述。 Update your code in following way 以下列方式更新您的代码

temp_ids=[]

for i in range(len(sorted_ids)-1):
    temp_ids.append(sorted_ids[i])

    if sorted_ids[i]+1 != sorted_ids[i+1] :
        for i in range(sorted_ids[i+1]-sorted_ids[i]-1):
            temp_ids.append("V") # appends as many V's as required

temp_ids.append(sorted_ids[-1]) # appends last element

This should work Suppose sorted array is [1,2,6] 这应该工作假设排序数组是[1,2,6]

So our desired output should be [1,2,'V','V','V',6]. 所以我们期望的输出应该是[1,2,'V','V','V',6]。 So every time 所以每一次

sorted_ids[i]+1 != sorted_ids[i+1]

condition holds, we will have to append few numbers of V's. 条件成立,我们将不得不附加几个V的数量。 Now to determine how many V's we append, see that between 2 and 6 , 3 V's will be appended. 现在要确定我们追加多少个V,看看在2到6之间,将附加3个V. So in general we append (sorted_ids[i+1] - sorted[i] -1) V's. 所以通常我们追加(sorted_ids [i + 1] - sorted [i] -1)V's。

Now see this line 现在看到这一行

for i in range(len(sorted_ids)-1):

Because of this line, our list only runs for [1,2] in [1,2,6] , and we never append 6 in our For Loop, so after exiting For Loop it was appended. 由于这一行,我们的列表仅在[1,2,6]中运行[1,2],并且我们永远不会在For循环中追加6,所以在退出For循环之后它会被追加。

First consider what ids should be in the list, assuming they start from 1 and end with the largest one present. 首先考虑列表中的id应该是什么,假设它们从1开始并以最大的id出现。 Then check if each expected id is actually present, and if not put a "V" there. 然后检查每个预期的id是否实际存在,如果没有,则在那里放置“V”。 As a side-effect this also sorts the list. 作为副作用,这也排序列表。

def arrange_tickets(tickets_list):
    ids = [int(ticket[1:]) for ticket in tickets_list]
    expected_ids = range(1, max(ids) + 1)
    return ["T%d" % n if n in ids else "V" for n in expected_ids]

tickets_list = ['T20', 'T5', 'T10', 'T1', 'T2', 'T8', 'T16', 'T17', 'T9', 'T4', 'T12', 'T13', 'T18']
print("Ticket ids of all the available students :")
print(tickets_list)
result=arrange_tickets(tickets_list)
print(result)   

result: 结果:

Ticket ids of all the available students :
['T20', 'T5', 'T10', 'T1', 'T2', 'T8', 'T16', 'T17', 'T9', 'T4', 'T12', 'T13', 'T18']

['T1', 'T2', 'V', 'T4', 'T5', 'V', 'V', 'T8', 'T9', 'T10', 'V', 'T12', 'T13', 'V', 'V', 'T16', 'T17', 'T18', 'V', 'T20']

You can use this itertools recipe to first group consecutive numbers: 您可以使用此itertools 配方首先对连续数字进行分组:

from itertools import groupby
from operator import itemgetter

def groupby_consecutive(lst):
    for _, g in groupby(enumerate(lst), lambda x: x[0] - x[1]):
        yield list(map(itemgetter(1), g))

sorted_ids = [1, 2, 4, 5, 8, 9, 10, 12, 13, 16, 17, 18, 20]
print(list(groupby_consecutive(lst=sorted_ids)))
# [[1, 2], [4, 5], [8, 9, 10], [12, 13], [16, 17, 18], [20]]

Then you can make a function that gets the interspersing V values from the previous groupings: 然后你可以创建一个函数,从前面的分组中获取散布的V值:

def interperse(lst):
    for x, y in zip(lst, lst[1:]):
        yield ["V"] * (y[0] - x[-1] - 1)

groups = list(groupby_consecutive(lst))
print(list(interperse(groups)))
# [['V'], ['V', 'V'], ['V'], ['V', 'V'], ['V']]

Then you can finally zip the above results together: 然后你最终可以将上述结果压缩在一起:

def add_prefix(lst, prefix):
    return [prefix + str(x) for x in lst]

def create_sequences(lst, prefix='T'):
    groups = list(groupby_consecutive(lst))
    between = list(interperse(groups))

    result = add_prefix(groups[0], prefix)
    for x, y in zip(between, groups[1:]):
        result.extend(x + add_prefix(y, prefix))

    return result

sorted_ids = [1, 2, 4, 5, 8, 9, 10, 12, 13, 16, 17, 18, 20]
print(create_sequences(lst=sorted_ids))
# ['T1', 'T2', 'V', 'T4', 'T5', 'V', 'V', 'T8', 'T9', 'T10', 'V', 'T12', 'T13', 'V', 'V', 'T16', 'T17', 'T18', 'V', 'T20']

In one shot, directly form the original array 在一次拍摄中,直接形成原始阵列

array = ['T20', 'T5', 'T10', 'T1', 'T2', 'T8', 'T16', 'T17', 'T9', 'T4', 'T12', 'T13', 'T18']

You can define a method that does all the job: 您可以定义执行所有工作的方法:

def add_vs_between_not_cons(array):
  iterable = sorted(array, key= lambda x: int(x[1:]))
  i, size = 0, len(iterable)
  while i < size:
    delta = int(iterable[i][1:]) - int(iterable[i-1][1:])
    for _ in range(delta-1):
      yield "V"
    yield iterable[i]
    i += 1

So, you can call: 所以,你可以打电话:

print(list(add_vs_between_not_cons(array)))

#=> ['T1', 'T2', 'V', 'T4', 'T5', 'V', 'V', 'T8', 'T9', 'T10', 'V', 'T12', 'T13', 'V', 'V', 'T16', 'T17', 'T18', 'V', 'T20']

my solution for infytq queries: 我的infytq查询解决方案:

def arrange_tickets(tickets_list):
    ids = [int(ticket[1:]) for ticket in tickets_list]
    expected_ids = range(1, max(ids) + 1)
    listt=["T%d" % n if n in ids else "V" for n in expected_ids]
    list1=listt[0:10]
    list2=listt[11:]
    for i in range(10):
        if 'V' in list2:
            list2.remove('V')
    for j in range(0,len(list2)):
        for n, i in enumerate(list1):
            if i == 'V':
                list1[n] = list2[j]
                j+=1
    return list1
tickets_list = ['T5','T7','T1','T2','T8','T15','T17','T19','T6','T12','T13']
print("Ticket ids of all the available students :")
print(tickets_list)
result=arrange_tickets(tickets_list)
print()
print("Ticket ids of the ten students in Group-1:")
print(result[0:10])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM