I have a list [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:
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.
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]
However, I'm not able to insert the exact no of V's at the right positions.
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]
Expected Result: [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]
So our desired output should be [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. Now to determine how many V's we append, see that between 2 and 6 , 3 V's will be appended. So in general we append (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.
First consider what ids should be in the list, assuming they start from 1 and end with the largest one present. Then check if each expected id is actually present, and if not put a "V" there. 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:
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:
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:
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])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.