Why Simple String's Character has So many array Dimensions? - python

I am currently working on a python's String and List.
When I assign string in variable str="string" and try to access it first character by str[0] it works perfectly and give "s".
But, when I try to find character str[0][0][0][0][0][0] it again gives "s". But when I give str[0][1] it gives an error:
IndexError: string index out of range
Its Correct. My Question is Why Simple String Character has So many array Dimensions? and it did not given any error and print 0 character of string when str[0][0][0][0][0][0]. What is Data Structure of String?
My Code is
str="string"
print((str[0][0][0][0][0][0][0][0])) # Working, but my Question is Why Working
print((str[1][0][0][0][0])) # Working
print((str[2][0][0][0][0])) # Working
print((str[3][0][0][0][0])) # Working
list=["0","p",0]
print(list[0][0][0]) # Working
My Output is:
s
t
r
i
0

Why shouldn't it work?
Indexing a string returns a one element string which is again indexable and returns the same value:
>>> 's'[0]
's'
since it consists of one element, you can continue indexing the zero-element [0] as much as you want.
This is explained in the standard type hierarchy section of the Python Reference manual:
Strings
A string is a sequence of values that represent Unicode code points. All the code points in the range U+0000 - U+10FFFF can be represented in a string. Python doesn’t have a char type; instead, every code point in the string is represented as a string object with length 1.
(Emphasis mine)
Side-note: Don't use names such as str, you mask the built-in str.

In Python a string is a sequence of characters, but characters are 1-char strings.
So if you access 'foobar'[0], you obtain 'f'. Since f is however a string, we can access the first character of that string. Since 'f'[0] is 'f'. As a result if you access a strings s with s[i][0][0][0], you thus keep accessing the first character of the string s.
If you write s[i][1] however, this will error, since s[i] is a one-character string, and thus you can not obtain the second character, since there is no such character.
The string itself is not multidimensional, you simply obtain a new string and call the index of that new string. You can add as many [0]s as you like.

The problem is not in Python, it is due to the fact that you assume there is a char type in Python (based on the title of this question).
A string in Python is an array of essentially single element strings. s[0] simply returns the string 's', not a character. s[0]...[0] can be thought of as an infinite recursion that keeps getting the same single element string, infinitely many times.
You can go as deep as you want: (in this case, in order to do it more than 997 times you will need to modify Python`s default allowed recursion depth)
def string_dive(s, count=0):
if count < 997:
count += 1
return string_dive(s[0], count)
else:
return s
print(string_dive('string'))
# 's'

Related

Two formatting strings in one with only one value

I want to have a string where I can format it with an integer so that it:
Adds a sign in front of the integer (+ for positive ints, - for negative ints)
Surround the signed int with parentheses (i.e. with ())
Left align the int with parentheses on the left, adding if necessary spaces to the end.
I know how to do these steps separately, but I haven't been able to combine them into a single string.
1 and 2 would be accomplished with for example '({:+d})'.format(3), this would result in (+3).
3 is done for an arbitrary string with '{:<5}'.format(3), this would result in 3 (4 trailing spaces).
My goal is to have a single string where I can call .format on only once, so
format_string.format(3)
would result in
(+3)
with one trailing space to make the string length 5.
Is this possible?
I've tried ({{:+d}:<5}) but this doesn't work as it thinks {:+d} is the field name to format with <5, which is obviously not the case.
I've also looked into f-strings, but these are not suitable for my use case as I call .format on the format string later than when it's created.
Any help would be most welcome!
Solution with one call for format:
def special_format_int(n, SPACES=5):
return '({:+d})'.format(n).ljust(SPACES)

How can I pack a string in struct.pack

I am trying to pack a string using struct.pack.
I am able to see complete value if I use integer type but when I want to use string I only see one character.
struct.pack("<1L",0xabcdabcd)
'\xab\xcd\ab\cd'
struct.pack("<1s","overflow")
'o' prints just s. I wanted it to print full string: overflow.
In the format string ("<1s") you're passing to struct.pack, the 1 denotes the maximum number of characters that field can store. (See the paragraph beginning "For the 's'..." in the struct documentation.) Since you're passing 1, it will only store the first character. You'll need to choose a length that will fit any string you want to store in the struct, and specify that. For example, to store the string "overflow" (8 characters) you could use "<8s":
>>> struct.pack("<8s", "overflow")
'overflow'

Python search string for two numbers, assign to variables

I have the following string a part of a file with lines with the same format.
CONST robtarget robttarget1:=[[-42277.480909368,-4997.36320197,2332.380745999],[0.347787091,-0.799426288,0.217080241,0.439133144],[0,0,0,0],[-35700.0,180.0,2200.000095367,0,9E9,9E9]];
I need to access two specific numbers and preform math on them. -35700.0 and 180.0.
I am struggling with getting those specific values and assign them to variables.
Just get rid of the part of the lines that are not the value and use eval to get the rest as a python variable.
The following line will break your string at the '=' character using split (so you will get 2 strings).
It will then get the second part of your string (the one which starts after the '='), remove the final ';' character and use eval to interpret the whole thing:
result = eval(s.split('=')[1][:-1])
Now you'll get a list of lists that you can extract your numbers from easily
You can split the string by the "=" and then use the ast module to convert the string list to a python list object and the use list indexing to fetch the required value
EX:
import ast
A = "CONST robtarget robttarget1:=[[-42277.480909368,-4997.36320197,2332.380745999],[0.347787091,-0.799426288,0.217080241,0.439133144],[0,0,0,0],[-35700.0,180.0,2200.000095367,0,9E9,9E9]];"
A = A.split("=")[1].replace(";", "") #Remove any non python string.
A = ast.literal_eval(A) #Convert string object to list object
print A[-1][0:2] # I have used slice to fetch the required value
Output:
[-35700.0, 180.0]

String slices/substrings/ranges in Python

I'm newbie in Python and I would like to know something that I found very curious.
Let's say I have this:
s = "hello"
Then:
s[1:4] prints "ell" which makes sense...
and then s[3:-1] prints 'l' only that does makes sense too..
But!
s[-1:3] which is same range but backwards returns an empty string ''... and s[1:10] or s[1:-20] is not throwing an error at all.. which.. from my point of view, it should produce an error right? A typical out-of-bounds error.. :S
My conclusion is that the range are always from left to right, I would like to confirm with the community if this is as I'm saying or not.
Thanks!
s[-1:3] returns the empty string because there is nothing in that range. It is requesting the range from the last character, to the third character, moving to the right, but the last character is already past the third character.
Ranges are by default left to right.
There are extended slices which can reverse the step, or change it's size. So s[-1:3:-1] will give you just 'o'. The last -1 in that slice is telling you that the slice should move from right to left.
Slices won't throw errors if you request a range that isn't in the string, they just return an empty string for those positions.
Ranges are "clamped" to the extent of the string... i.e.
s[:10]
will return the first 10 characters, or less if the string is not long enough.
A negative index means starting counting from the end, so s[-3:] takes the last three characters (or less if the string is shorter).
You can have range backward but you need to use an explicit step, like
s[10:5:-1]
You can also simply get the reverse of a string with
s[::-1]
or the string composed by taking all chars in even position with
s[::2]

python trying to remove single apostrophe

I'm using a program called CityEngine which has a python element to it.
The problem: I've just called a function on an object and returns me a list of numbers, xyz. I split the xyz into their own names. I also call a function to retrieve a different attribute related to this object to replace the previously retrieved y value.
Now, when I print the y value, it contains numerical characters only apart from decimal place.
When I incorporate the y value into a new list, it's value has single apostrophe around it.
For example, print(y) returns 5.0000000
If I place it like this position[x,y,z] I get a print(position) of [0, '5.000000' , 0]. The program can't read the single apostrophes so ignored the value completely.
I've tried .remove("'","") and .strip() and nothing.
Any help would be appreciated.
Thanks.
That looks more as if the function were not returning a number but a string. So, in order to deal with it, you’ll have to convert the string using either int() or float().
In general, if you do a print(l) on some list of items, each item will be printed with the output of it’s __repr__ method. Convention has it that the __repr__ method of string wraps the string with single apostrophes, whereas numbers do not get wrapped. This is to remove potential ambiguity. Hence, a print(l) which returned
[0, '5.00000', 0.1]
would be a list containing an int, a str and a float.
Convert it to float ... It is a string, so you need to do string to float conversion

Categories

Resources