The slicing of s is non-inclusive.
s[start:end]
Meaning the output is up to but not including the end value. This means that the line
print (s[i:i+1])
is equivalent to
print (s[i])
According to this reference (https://blog.finxter.com/daily-python-puzzle-overshoot-index-slicing/)
A little-known feature of slicing is that it has robust end indices. Slicing is robust even if the end index is greater than the maximal sequence index. The slice just takes all elements up to the maximal element. If the start index is out of bounds as well, it returns the empty slice.
The follow code gives
s ="123"
roman = {"I":1, "IV":4, "V":5, "IX":9, "X":10, "XL":40, "L":50,
"XC":90, "C":100, "CD":400, "D":500, "CM":900, "M":1000}
out = 0
n = len(s)
i = 0
while i < n:
print (s[i:i+2])
i = i + 1
print(s[5:7])
gives:
12
23
3
Answer from Klimunmm on Stack OverflowNot really understanding when to use for I in string vs for I in range(len(string))
loops - Using range function in Python - Stack Overflow
Convert range(r) to list of strings of length 2 in python - Stack Overflow
python range and string - Stack Overflow
I had the same issue and there is a perfect solution to it -zfill method
An example of usage:
>>> str('1').zfill(7)
'0000001'
What you need to do is to create a generator for N numbers and fill its string representation with zeros.
>>> for i in range(1, 18):
... str(i).zfill(2)
...
'01'
'02'
'03'
...
'16'
'17'
>>> [str(i).zfill(2) for i in range(1,18)]
['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17']
Just looking for clarification for this very simple thing. Please correct me if Iβm wrong but from what I understand, in for i in string, it takes each element in the string over the entire length. For i in range(len(string)) it indexes the elements and looks at the elements at each index so at position 0, string =βxβ and at 1 string= βdβ ect.
If this is correct, Iβm afraid I still donβt see the difference by way of when to use each or what purpose they serve.
Use string formatting and list comprehension:
>>> lst = range(11)
>>> ["{:02d}".format(x) for x in lst]
['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10']
or format:
>>> [format(x, '02d') for x in lst]
['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10']
zfill does exactly what you want and doesn't require you to understand an arcane mini-language as with the various types of string formatting. There's a place for that, but this is a simple job with a ready-made built-in tool.
ranger = [str(x).zfill(2) for x in range(r)]
for i in range(0,n):
print(i,"one thousand.",end='')
print()
Here's a solution that solves your problem but is code-golfed enough to look weird as a homework answer at this level:
print(' '.join(map(lambda x: "%d one thousand." % x, range(1, n))))
Explanation!
- A "lambda function" is simply a very small way of writing a function without naming it. In this case,
lambda x: "%d one thousand." % xwill take in a numberxand output the string"1 one thousand"if x=1, for example. - The
%operator used in that lambda is a shortcut for string.format. That's a bit too much to explain right now, but here it basically means "insert the value ofxwhere the%dis". - The
mapfunction is a fancy way of writing an entireforloop in a single line. It takes a function and a list, and applies the function to each item in the list. ' '.joinis a peculiarity of Python. What it does is take a list and turn it into a string by putting a space between each of the items. You would think that it'd be a function you call on the list, but in Python it's a function on the string instead.
Here's a much more clearly written version:
numbers = range(1, n)
make_count_string = lambda x: "%d one thousand." % x
count_strings = map(make_count_string, numbers)
combined_string = ' '.join(count_strings)
print(combined_string)