A permutation considering one item has to be prior to another - python-2.7

I have a problem regarding the permutation problem.
I have a list of (1,2,3,4,5,6), then if I apply the following code:
import itertools
a = list(itertools.permutations([1,2,3,4,5,6],6))
I would get 720 permutations. Instead, I have a specific sequence that:
1 has to be ahead of 5,
2 has to be ahead of 6,
3 has to be ahead of 7,
4 has to be ahead of 8,
so does anyone know how to generate permutations consider the rules above?
Thanks,

You create your permutations and filter them:
import itertools
a = list(itertools.permutations([1,2,3,4,5,6,7,8],8))
# your rules for filter
def IsOk(tupl):
one = tupl.index(1)
two = tupl.index(2)
thr = tupl.index(3)
fou = tupl.index(4)
fiv = tupl.index(5)
six = tupl.index(6)
sev = tupl.index(7)
eig = tupl.index(8)
return one > fiv and two > six and thr > sev and fou > eig
print(a)
filtered = filter(lambda x: IsOk(x), a)
print(*filtered)
print(len(*filtered))
I had to increase your permutations to 8 so all your rules could be processed.
This reduces the permutations from 40320 down to 2520.

Related

In the PuLP scheduling problem, how to bring/group the consecutive Zeros together and still get an optimal solution? For meal breaks in the schedule

Solving an agent scheduling problem using PuLP.
8 hours of shift, 4 agents.
I have to generate an output where the 8 hrs of shift is divided into 15-minute intervals. Hence, 32 total periods. (the 15 minute periods of an 8 hour shift is a fixed input, which is not allowed to be tweaked.)
At any given period, there need to be a minimum of 3 agents working (i.e.not on break)
Now, there needs to be a 1 hour meal break, and a 30 min short break.
So, for 1 hour meal break, I will have to combine 4 periods of 15 mins, and for the 30 min short break, I'll have to combine 2 periods of 15 mins.
I tried getting 26 counts of 1... and, 6 counts of 0.
The idea was to then combine 4 zeros together (meal break), and the remaining 2 zeros together (short break).
The current LpStatus is 'infeasible'... if i remove the constraint where i am trying to club the zeros, then the solution is optimal, or else it shows infeasible.
Have also pasted my final dataframe output screenshots.
import pandas as pd
import numpy as np
import scipy as sp
import seaborn as sns
import matplotlib.pyplot as plt
from pandas.plotting import table
import os, sys, json
from pulp import *
%matplotlib inline
# agent works either 1, 2, 3, 4, 5, 6, 7, 8 hours per week.
working_periods = [26]
# maximum periods that agent will work (7 hrs in each shift)
max_periods = 26
# planning_length
planning_length = 1 # TODO: Total number of shifts i.e. 21 in our case
# Number of periods per shift:
daily_periods = [0, 1, 2, 3, 4, 5, 6, 7, 8,9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
# Label the days from Monday to Sunday.
s = ['Period']
# Create the required_agents dataframe
col_2 = range(0, 1*planning_length)
required_agents_per_period = pd.DataFrame(data = None, columns=s, index = daily_periods)
for j in col_2:
# Small number is better for visualization.
required_agents_per_period.iloc[0][j] = 3
required_agents_per_period.iloc[1][j] = 3
required_agents_per_period.iloc[2][j] = 3
required_agents_per_period.iloc[3][j] = 3
required_agents_per_period.iloc[4][j] = 3
required_agents_per_period.iloc[5][j] = 3
required_agents_per_period.iloc[6][j] = 3
required_agents_per_period.iloc[7][j] = 3
required_agents_per_period.iloc[8][j] = 3
required_agents_per_period.iloc[9][j] = 3
required_agents_per_period.iloc[10][j] = 3
required_agents_per_period.iloc[11][j] = 3
required_agents_per_period.iloc[12][j] = 3
required_agents_per_period.iloc[13][j] = 3
required_agents_per_period.iloc[14][j] = 3
required_agents_per_period.iloc[15][j] = 3
required_agents_per_period.iloc[16][j] = 3
required_agents_per_period.iloc[17][j] = 3
required_agents_per_period.iloc[18][j] = 3
required_agents_per_period.iloc[19][j] = 3
required_agents_per_period.iloc[20][j] = 3
required_agents_per_period.iloc[21][j] = 3
required_agents_per_period.iloc[22][j] = 3
required_agents_per_period.iloc[23][j] = 3
required_agents_per_period.iloc[24][j] = 3
required_agents_per_period.iloc[25][j] = 3
required_agents_per_period.iloc[26][j] = 3
required_agents_per_period.iloc[27][j] = 3
required_agents_per_period.iloc[28][j] = 3
required_agents_per_period.iloc[29][j] = 3
required_agents_per_period.iloc[30][j] = 3
required_agents_per_period.iloc[31][j] = 3
# List of number of agents required in specific periods
r_p = required_agents_per_period.values.swapaxes(0,1).ravel()
print("The number of agents required for each period is: ")
print (r_p)
print("Total no. of periods is: ", len(r_p))
print ("\nIn matrix form:")
print (required_agents_per_period)
# Total number of the agents
total = 4
print ("\nTotal number of agents are: {}".format(total))
# Create agents_id tag
agent_id_working_in_shift = ['agent7', 'agent10', 'agent13', 'agent18'] # TODO: Important: Here agent_id will be array of agents that will be extracted from dataframe.
print ("\nThe agents are: ")
print (agent_id_working_in_shift)
# Total periods
periods = range(1*32)
agents_per_shift = range(total)
## Create shift names based on index:
period_name = []
for p in periods:
period_name.append(s[0] + '_' + 'P' + str(p))
print("The periods are: ")
print(periods)
print("\nThe names of corresponding periods are: ")
print(period_name)
print("\nThe agents are: ")
print(agents_per_shift)
def LpProb():
# The prob variable is created to contain the problem data
prob = LpProblem("Agents Meal Scheduling Per Shift",LpMinimize)
# Creating the variables.
var = {
(n, p): pulp.LpVariable(
"schdule_{0}_{1}".format(n, p), cat = "Binary")
for n in agents_per_shift for p in periods
}
# add constraints:
for n in agents_per_shift:
for p in periods:
prob.addConstraint(var[(n,p)] <= 1)
# add constraints:
# Exactly 32 working periods per shift
for n in agents_per_shift:
prob.addConstraint(
sum(var[(n,p)] for p in periods) == 26
)
for n in agents_per_shift:
for p in periods:
if(p == periods[-1] or p == periods[-2] or p == periods[-3]):
continue
prob.addConstraint(var[(n,p)] + var[(n,p+1)] + var[(n,p+2)] + var[(n,p+3)] == 0)
# add constraints
# for each shift, the numbers of working agents should be greater than or equal to
# the required numbers of agents
for p in periods:
try:
prob.addConstraint(
sum(var[(n,p)] for n in agents_per_shift) >= 3
)
except:
print("len(periods) should be equal to len(agents_per_shift)")
sys.exit(-1)
prob.objective = sum(var[(n,p)] for n in agents_per_shift for p in periods)
return var, prob
# Run the solver
var, prob = LpProb()
prob.solve()
print(LpStatus[prob.status])
def agent_scheduling(var = var):
schedule = pd.DataFrame(data=None, index = agent_id_working_in_shift, columns = period_name)
for k, v in var.items():
n, p = k[0], k[1]
schedule.iloc[n][p] = int(value(v)) # pulp.value()
return schedule
schedule = agent_scheduling()
schedule.T
I was expecting an output of only zeros and one.
Want to combine four 0's as meal break, that need to be consecutive, and then a two 0's consecutive for short break (remaining 26 cells should be 1's)
Also, only 1 agent can be on a break (0), the other 3 agents needs to be working in that period (1)
OUTPUTS:-
enter image description here
enter image description here
enter image description here

how do you draw random numbers from a list and put them in another

I do not know how to draw 2 or more different numbers and put them in another list, so far I have tried this:
import random
def jugar(m):
m = list(range(1, 14, 1)) * m
random.shuffle(m)
player1 = []
for n in m:
random.choice(m)
player1.append(n)
if n + n == 21:
print("Nano jack")
elif n + n < 21:
random.choice(m)
player1.append(n)
elif n + n > 21:
print("Loser")
return player1
jugar(1)
but this returns me 2 equal numbers, it is similar to the game of blackjack, I want it to keep adding random numbers until it reaches 21 or more, thanks for the help in advance
You can use choice method to randomly select an item from a given list.
Use it in a for loop to randomly select more items.
import random
the_list = [1, 2, 3, 4]
new_list = []
for i in range(3):
value = random.choice(the_list)
new_list.append(value)

Counting matrix pairs using a threshold

I have a folder with hundreds of txt files I need to analyse for similarity. Below is an example of a script I use to run similarity analysis. In the end I get an array or a matrix I can plot etc.
I would like to see how many pairs there are with cos_similarity > 0.5 (or any other threshold I decide to use), removing cos_similarity == 1 when I compare the same files, of course.
Secondly, I need a list of these pairs based on file names.
So the output for the example below would look like:
1
and
["doc1", "doc4"]
Will really appreciate your help as I feel a bit lost not knowing which direction to go.
This is an example of my script to get the matrix:
doc1 = "Amazon's promise of next-day deliveries could be investigated amid customer complaints that it is failing to meet that pledge."
doc2 = "The BBC has been inundated with comments from Amazon Prime customers. Most reported problems with deliveries."
doc3 = "An Amazon spokesman told the BBC the ASA had confirmed to it there was no investigation at this time."
doc4 = "Amazon's promise of next-day deliveries could be investigated amid customer complaints..."
documents = [doc1, doc2, doc3, doc4]
# In my real script I iterate through a folder (path) with txt files like this:
#def read_text(path):
# documents = []
# for filename in glob.iglob(path+'*.txt'):
# _file = open(filename, 'r')
# text = _file.read()
# documents.append(text)
# return documents
import nltk, string, numpy
nltk.download('punkt') # first-time use only
stemmer = nltk.stem.porter.PorterStemmer()
def StemTokens(tokens):
return [stemmer.stem(token) for token in tokens]
remove_punct_dict = dict((ord(punct), None) for punct in string.punctuation)
def StemNormalize(text):
return StemTokens(nltk.word_tokenize(text.lower().translate(remove_punct_dict)))
nltk.download('wordnet') # first-time use only
lemmer = nltk.stem.WordNetLemmatizer()
def LemTokens(tokens):
return [lemmer.lemmatize(token) for token in tokens]
remove_punct_dict = dict((ord(punct), None) for punct in string.punctuation)
def LemNormalize(text):
return LemTokens(nltk.word_tokenize(text.lower().translate(remove_punct_dict)))
from sklearn.feature_extraction.text import CountVectorizer
LemVectorizer = CountVectorizer(tokenizer=LemNormalize, stop_words='english')
LemVectorizer.fit_transform(documents)
tf_matrix = LemVectorizer.transform(documents).toarray()
from sklearn.feature_extraction.text import TfidfTransformer
tfidfTran = TfidfTransformer(norm="l2")
tfidfTran.fit(tf_matrix)
tfidf_matrix = tfidfTran.transform(tf_matrix)
cos_similarity_matrix = (tfidf_matrix * tfidf_matrix.T).toarray()
from sklearn.feature_extraction.text import TfidfVectorizer
TfidfVec = TfidfVectorizer(tokenizer=LemNormalize, stop_words='english')
def cos_similarity(textlist):
tfidf = TfidfVec.fit_transform(textlist)
return (tfidf * tfidf.T).toarray()
cos_similarity(documents)
Out:
array([[ 1. , 0.1459739 , 0.03613371, 0.76357693],
[ 0.1459739 , 1. , 0.11459266, 0.19117117],
[ 0.03613371, 0.11459266, 1. , 0.04732164],
[ 0.76357693, 0.19117117, 0.04732164, 1. ]])
As I understood your question, you want to create a function that reads the output numpy array and a certain value (threshold) in order to return two things:
how many docs are bigger than or equal the given threshold
the names of these docs.
So, here I've made the following function which takes three arguments:
the output numpy array from cos_similarity() function.
list of document names.
a certain number (threshold).
And here it's:
def get_docs(arr, docs_names, threshold):
output_tuples = []
for row in range(len(arr)):
lst = [row+1+idx for idx, num in \
enumerate(arr[row, row+1:]) if num >= threshold]
for item in lst:
output_tuples.append( (docs_names[row], docs_names[item]) )
return len(output_tuples), output_tuples
Let's see it in action:
>>> docs_names = ["doc1", "doc2", "doc3", "doc4"]
>>> arr = cos_similarity(documents)
>>> arr
array([[ 1. , 0.1459739 , 0.03613371, 0.76357693],
[ 0.1459739 , 1. , 0.11459266, 0.19117117],
[ 0.03613371, 0.11459266, 1. , 0.04732164],
[ 0.76357693, 0.19117117, 0.04732164, 1. ]])
>>> threshold = 0.5
>>> get_docs(arr, docs_names, threshold)
(1, [('doc1', 'doc4')])
>>> get_docs(arr, docs_names, 1)
(0, [])
>>> get_docs(lst, docs_names, 0.13)
(3, [('doc1', 'doc2'), ('doc1', 'doc4'), ('doc2', 'doc4')])
Let's see how this function works:
first, I iterate over every row of the numpy array.
Second, I iterate over every item in the row whose index is bigger than the row's index. So, we are iterating in a traingular shape like so:
and that's because each pair of documents is mentioned twice in the whole array. We can see that the two values arr[0][1] and arr[1][0] are the same. You also should notice that the diagonal items arn't included because we knew for sure that they are 1 as evey document is very similar to itself :).
Finally, we get the items whose values are bigger than or equal the given threshold, and return their indices. These indices are used later to get the documents names.

Find top 5 word lengths in a text

I'm trying to write a program that takes two functions:
count_word_lengths which takes the argument text, a string of text, and returns a default dictionary that records the count for each word length. An example call to this function:
top5_lengths which takes the same argument text and returns a list of the top 5 word lengths.
Note: that in the event that
two lengths have the same frequency, they should be sorted in descending order. Also, if there are fewer than 5 word lengths it should return a shorter list of the sorted word lengths.
Example calls to count_word_lengths:
count_word_lengths("one one was a racehorse two two was one too"):
defaultdict(<class 'int'>, {1: 1, 3: 8, 9: 1})
Example calls to top5_lengths:
top5_lengths("one one was a racehorse two two was one too")
[3, 9, 1]
top5_lengths("feather feather feather chicken feather")
[7]
top5_lengths("the swift green fox jumped over a cool cat")
[3, 5, 4, 6, 1]
My current code is this, and seems to output all these calls, however it is failing a hidden test. What type of input am I not considering? Is my code actually behaving correctly? If not, how could I fix this?
from collections import defaultdict
length_tally = defaultdict(int)
final_list = []
def count_word_lengths(text):
words = text.split(' ')
for word in words:
length_tally[len(word)] += 1
return length_tally
def top5_word_lengths(text):
frequencies = count_word_lengths(text)
list_of_frequencies = frequencies.items()
flipped = [(t[1], t[0]) for t in list_of_frequencies]
sorted_flipped = sorted(flipped)
reversed_sorted_flipped = sorted_flipped[::-1]
for item in reversed_sorted_flipped:
final_list.append(item[1])
return final_list
One thing to note is that you do not account for an empty string. That would cause count() to return null/undefined. Also you can use iteritems() during list comprehension to get the key and value from a dict like for k,v in dict.iteritems():
I'm not a Python guy, but I can see a few things that might cause issues.
You keep referring to top5_lengths, but your code has a function called top5_word_lengths.
You use a function called count_lengths that isn't defined anywhere.
Fix these and see what happens!
Edit:
This shouldn't impact your code, but it's not great practice for your functions to update variables outside their scope. You probably want to move the variable assignments at the top to functions where they're used.
Not really an answer, but an alternative way of tracking words instead of just lengths:
from collections import defaultdict
def count_words_by_length(text):
words = [(len(word),word) for word in text.split(" ")]
d = defaultdict(list)
for k, v in words:
d[k].append(v)
return d
def top_words(dict, how_many):
return [{"word_length": length, "num_words": len(words)} for length, words in dict.items()[-how_many:]]
Use as follows:
my_dict = count_words_by_length('hello sir this is a beautiful day right')
my_top_words = num_top_words_by_length(my_dict, 5)
print(my_top_words)
print(my_dict)
Output:
[{'word_length': 9, 'num_words': 1}]
defaultdict(<type 'list'>, {1: ['a'], 2: ['is'], 3: ['sir', 'day'], 4: ['this'], 5: ['hello', 'right'], 9: ['beautiful']})

Pythonic way to convert a list of integers into a string of comma-separated ranges

I have a list of integers which I need to parse into a string of ranges.
For example:
[0, 1, 2, 3] -> "0-3"
[0, 1, 2, 4, 8] -> "0-2,4,8"
And so on.
I'm still learning more pythonic ways of handling lists, and this one is a bit difficult for me. My latest thought was to create a list of lists which keeps track of paired numbers:
[ [0, 3], [4, 4], [5, 9], [20, 20] ]
I could then iterate across this structure, printing each sub-list as either a range, or a single value.
I don't like doing this in two iterations, but I can't seem to keep track of each number within each iteration. My thought would be to do something like this:
Here's my most recent attempt. It works, but I'm not fully satisfied; I keep thinking there's a more elegant solution which completely escapes me. The string-handling iteration isn't the nicest, I know -- it's pretty early in the morning for me :)
def createRangeString(zones):
rangeIdx = 0
ranges = [[zones[0], zones[0]]]
for zone in list(zones):
if ranges[rangeIdx][1] in (zone, zone-1):
ranges[rangeIdx][1] = zone
else:
ranges.append([zone, zone])
rangeIdx += 1
rangeStr = ""
for range in ranges:
if range[0] != range[1]:
rangeStr = "%s,%d-%d" % (rangeStr, range[0], range[1])
else:
rangeStr = "%s,%d" % (rangeStr, range[0])
return rangeStr[1:]
Is there a straightforward way I can merge this into a single iteration? What else could I do to make it more Pythonic?
>>> from itertools import count, groupby
>>> L=[1, 2, 3, 4, 6, 7, 8, 9, 12, 13, 19, 20, 22, 23, 40, 44]
>>> G=(list(x) for _,x in groupby(L, lambda x,c=count(): next(c)-x))
>>> print ",".join("-".join(map(str,(g[0],g[-1])[:len(g)])) for g in G)
1-4,6-9,12-13,19-20,22-23,40,44
The idea here is to pair each element with count(). Then the difference between the value and count() is constant for consecutive values. groupby() does the rest of the work
As Jeff suggests, an alternative to count() is to use enumerate(). This adds some extra cruft that needs to be stripped out in the print statement
G=(list(x) for _,x in groupby(enumerate(L), lambda (i,x):i-x))
print ",".join("-".join(map(str,(g[0][1],g[-1][1])[:len(g)])) for g in G)
Update: for the sample list given here, the version with enumerate runs about 5% slower than the version using count() on my computer
Whether this is pythonic is up for debate. But it is very compact. The real meat is in the Rangify() function. There's still room for improvement if you want efficiency or Pythonism.
def CreateRangeString(zones):
#assuming sorted and distinct
deltas = [a-b for a, b in zip(zones[1:], zones[:-1])]
deltas.append(-1)
def Rangify((b, p), (z, d)):
if p is not None:
if d == 1: return (b, p)
b.append('%d-%d'%(p,z))
return (b, None)
else:
if d == 1: return (b, z)
b.append(str(z))
return (b, None)
return ','.join(reduce(Rangify, zip(zones, deltas), ([], None))[0])
To describe the parameters:
deltas is the distance to the next value (inspired from an answer here on SO)
Rangify() does the reduction on these parameters
b - base or accumulator
p - previous start range
z - zone number
d - delta
To concatenate strings you should use ','.join. This removes the 2nd loop.
def createRangeString(zones):
rangeIdx = 0
ranges = [[zones[0], zones[0]]]
for zone in list(zones):
if ranges[rangeIdx][1] in (zone, zone-1):
ranges[rangeIdx][1] = zone
else:
ranges.append([zone, zone])
rangeIdx += 1
return ','.join(
map(
lambda p: '%s-%s'%tuple(p) if p[0] != p[1] else str(p[0]),
ranges
)
)
Although I prefer a more generic approach:
from itertools import groupby
# auxiliary functor to allow groupby to compare by adjacent elements.
class cmp_to_groupby_key(object):
def __init__(self, f):
self.f = f
self.uninitialized = True
def __call__(self, newv):
if self.uninitialized or not self.f(self.oldv, newv):
self.curkey = newv
self.uninitialized = False
self.oldv = newv
return self.curkey
# returns the first and last element of an iterable with O(1) memory.
def first_and_last(iterable):
first = next(iterable)
last = first
for i in iterable:
last = i
return (first, last)
# convert groups into list of range strings
def create_range_string_from_groups(groups):
for _, g in groups:
first, last = first_and_last(g)
if first != last:
yield "{0}-{1}".format(first, last)
else:
yield str(first)
def create_range_string(zones):
groups = groupby(zones, cmp_to_groupby_key(lambda a,b: b-a<=1))
return ','.join(create_range_string_from_groups(groups))
assert create_range_string([0,1,2,3]) == '0-3'
assert create_range_string([0, 1, 2, 4, 8]) == '0-2,4,8'
assert create_range_string([1,2,3,4,6,7,8,9,12,13,19,20,22,22,22,23,40,44]) == '1-4,6-9,12-13,19-20,22-23,40,44'
This is more verbose, mainly because I have used generic functions that I have and that are minor variations of itertools functions and recipes:
from itertools import tee, izip_longest
def pairwise_longest(iterable):
"variation of pairwise in http://docs.python.org/library/itertools.html#recipes"
a, b = tee(iterable)
next(b, None)
return izip_longest(a, b)
def takeuntil(predicate, iterable):
"""returns all elements before and including the one for which the predicate is true
variation of http://docs.python.org/library/itertools.html#itertools.takewhile"""
for x in iterable:
yield x
if predicate(x):
break
def get_range(it):
"gets a range from a pairwise iterator"
rng = list(takeuntil(lambda (a,b): (b is None) or (b-a>1), it))
if rng:
b, e = rng[0][0], rng[-1][0]
return "%d-%d" % (b,e) if b != e else "%d" % b
def create_ranges(zones):
it = pairwise_longest(zones)
return ",".join(iter(lambda:get_range(it),None))
k=[0,1,2,4,5,7,9,12,13,14,15]
print create_ranges(k) #0-2,4-5,7,9,12-15
def createRangeString(zones):
"""Create a string with integer ranges in the format of '%d-%d'
>>> createRangeString([0, 1, 2, 4, 8])
"0-2,4,8"
>>> createRangeString([1,2,3,4,6,7,8,9,12,13,19,20,22,22,22,23,40,44])
"1-4,6-9,12-13,19-20,22-23,40,44"
"""
buffer = []
try:
st = ed = zones[0]
for i in zones[1:]:
delta = i - ed
if delta == 1: ed = i
elif not (delta == 0):
buffer.append((st, ed))
st = ed = i
else: buffer.append((st, ed))
except IndexError:
pass
return ','.join(
"%d" % st if st==ed else "%d-%d" % (st, ed)
for st, ed in buffer)
Here is my solution. You need to keep track of various pieces of information while you iterate through the list and create the result - this screams generator to me. So here goes:
def rangeStr(start, end):
'''convert two integers into a range start-end, or a single value if they are the same'''
return str(start) if start == end else "%s-%s" %(start, end)
def makeRange(seq):
'''take a sequence of ints and return a sequence
of strings with the ranges
'''
# make sure that seq is an iterator
seq = iter(seq)
start = seq.next()
current = start
for val in seq:
current += 1
if val != current:
yield rangeStr(start, current-1)
start = current = val
# make sure the last range is included in the output
yield rangeStr(start, current)
def stringifyRanges(seq):
return ','.join(makeRange(seq))
>>> l = [1,2,3, 7,8,9, 11, 20,21,22,23]
>>> l2 = [1,2,3, 7,8,9, 11, 20,21,22,23, 30]
>>> stringifyRanges(l)
'1-3,7-9,11,20-23'
>>> stringifyRanges(l2)
'1-3,7-9,11,20-23,30'
My version will work correctly if given an empty list, which I think some of the others will not.
>>> stringifyRanges( [] )
''
makeRanges will work on any iterator that returns integers and lazily returns a sequence of strings so can be used on infinite sequences.
edit: I have updated the code to handle single numbers that are not part of a range.
edit2: refactored out rangeStr to remove duplication.
how about this mess...
def rangefy(mylist):
mylist, mystr, start = mylist + [None], "", 0
for i, v in enumerate(mylist[:-1]):
if mylist[i+1] != v + 1:
mystr += ["%d,"%v,"%d-%d,"%(start,v)][start!=v]
start = mylist[i+1]
return mystr[:-1]