what is difference betwen string and tuple? - python

Can anyone explain what is difference between string and tuple
a="string"
b=("s","t","r","i","n","g")
both are immutable.

They're different types.
"str" in a # True
("s", "t", "r") in b # False
Which means they have different methods, different use cases, different meanings, different implementations, etc. etc. etc.... Consider:
datapoint_tuple = (datetime.datetime.now(), 42)
datapoint_str = ...???
Essentially the only thing they have in common is their immutability.

Strings are immutable in python which means it cannot be changed once created, if you want to update it then a new string is to be created for example.
s="Abcdef"
c=s+'112'
print s,c
you can extract value using index, find values but cannot modify it
To access substrings, use the square brackets for slicing along with the index or indices to obtain your substring
Tuple they are immutable like strings and sequence like lists.They are used to store data just like list, just like string you cannot update or edit the tuple to change it you have to create a new one just like strings.Tuples can be created using parenthesis () and data is inserted using comas.
t1=(1,2,3,'hi')
print type(t1)
print t1

A string is a sequence of unicode characters with quotation marks on either side of the sequence.
Example: mystring = "this is a string"
A tuple is an ordered sequence of objects or characters separated by commas with parentheses on either side of the sequence.
Example: mytuple = (7, "u", "p", 1, "e')
They are, however, similar in the fact that they are both immutable

t1 = (1,2,3,4)
t2 =(1,2,3,4)
print( t1 is t2)
Output: True
This means they refer to the same object and string does the same thing. But tuples comes into play when few data need to stay together. For example: file name, it's size and type. Even when you return multiple values they are returned as a tuple.
def convert_seconds(seconds):
hours = seconds//3600
minutes = (seconds - hours*3600)//60
remaining_seconds = seconds- hours*3600 - minutes*60
return hours,minutes,remaining_seconds
result = convert_seconds(5000)
print(type(result))
output: <class 'tuple'>
Once you know why using it, it will clear your confusion.

tuple use a trailing comma:
tuple_a = 'a',
print(type(tuple_a)) # <class 'tuple'>
string don't use:
string_a = 'a'
print(type(string_a)) # <class 'str'>
but string and tuple has some same characteristics。
eg:
1、indexing and slicing
string_same = 'string'
tuple_same = ('s', 't', 'r', 'i', 'n', 'g')
print(string_same[0], tuple_same[0]) # s s
print(string_same[:-1], tuple_same[:-1]) # strin ('s', 't', 'r', 'i', 'n')
2、Immutability
means string and tuple not suport item assigment
string_same[0] = 'python_'
tuple_same[0] = 'python_'
TypeError: 'str' object does not support item assignment
TypeError: 'tuple' object does not support item assignment
you could find all of the diffrent from the Doc.
including other tyeps build-in types.
https://docs.python.org/3/library/stdtypes.html?highlight=tuple#tuple

Related

Parse String into namedtuple object

How to read back string, into namedtuple?
import collections
from typing import Sequence, Iterator
import ast
Range = collections.namedtuple("Range", ["key", "min", "max", "in_range" ])
Ranges to string
Test object to string:
r1 = tools.Range(key='T1',min=-0.01,max=0.19, in_range=True)
r2 = tools.Range(key='T2',min=2,max=10, in_range=False)
r3 = tools.Range(key='T3',min=225000,max=1583515.5, in_range=True)
rs = [r1, r2, r3]
rstr = str(rs)
print(rstr)
# output:
# [Range(key='T1', min=-0.01, max=0.19, in_range=True), Range(key='T2', min=2, max=10, in_range=False), Range(key='T3', min=225000, max=1583515.5, in_range=True)]
How to read same or similar string now into object (list of Range)?
Parse back String to Ranges
What I've tried with most hope of success:
source_string = "[Range(key='T1', min=-0.01, max=0.19, in_range=True), Range(key='T2', min=2, max=10, in_range=False), Range(key='T3', min=225000, max=1583515.5, in_range=True)]"
source = ast.literal_eval(source_string)
ranges = tools.Range(key=source["key"],min=float(source["min"]), max=float(source["max"]), in_range=bool(source["in_range"]))
I did also variants, with no success. I am open to change the string syntax to get the ranges object generate.
The ast.literal_eval function can only parse the following types:
strings
bytes
numbers
tuples
lists
dicts
sets
booleans
None and Ellipsis
This also means that it can only parse a tuple, list, dict, or set containing these specific types. It cannot parse a list of namedtuple objects. So you will have to either:
Create your own method that parses a string of the format "Range(key= ...(etc.)", OR
Remove the attribute names/keywords from your string, leaving simply a tuple for each element. You can then use python's built-in map function in combination with the namedtuple._make method to parse the list of tuples:
source_string = "[('T1', -0.01, 0.19, True), ('T2', 2, 10, False), ('T3', 225000, 1583515.5, True)]"
source = ast.literal_eval(source_string)
ranges = list(map(Range._make, source))
If you really need Range(...) and/or key=..., min=... to be a part of the string, you could potentially pre-process the string using regex.

Python-Value from list as a argument of other list

I have a problem with lists because I want to get value from the list named test_table with value from A_table as an argument. Is there any way to get the proper result? Of course the lists aren't empty and when I run it I get Process finished with exit code -1073740791 (0xC0000409)
for x in range(len(A_table)):
print(test_table[A_table[x]])
Edit:
List_A is generated like this: (i think that the problem is type-string not integer, but with int type my function doesn't work):
A_letter = [find_all(sentence, 'A')]
A_string = ' '.join(map(str, A_letter[0]))
data = A_string.split() # split string into a list
for temp in data:
A_table.append(temp)
Is this what you are trying to do?
This code looks into test_list and if the value is found, prints it by calling the list.index() function.
list_a =[1,2,3,4]
test_list = [3,5,8,9]
for i in range(len(list_a)):
if list_a[i] in test_list:
print(test_list[test_list.index(list_a[i])])
//output = 3
To start, I don't know where that find_all function is defined, but if it behaves like re.findall (which you should probably use), then it returns a list already, so by defining A_letter = [find_all(sentence, 'A')], you have a list of list of matches.
Consider this example:
>>> import re
>>> sentence = 'A wonderful sample of A test string'
>>> re.findall('A', sentence)
['A', 'A']
Moving on, your A_table has a list of str. So there is no direct way to index into another list using the values inside of A_table. For example, even if test_table has the values ['A', 'B', 'C'], the valid index values are still "0", "1", and "2", i.e. I cannot get test_table['A'], because lists may only be indexed by int.
If you want to get the index of a certain value (e.g. "A") in a list, you can use the index function of list, which returns the first index of the provided value, or raises a ValueError if the value is not found.
For example:
>>> import re
>>>
>>> test_table=['Q','F','R','A','B','X']
>>>
>>> sentence = 'A wonderful sample of A test string'
>>> A_table = re.findall('A', sentence)
>>>
>>> for match in A_table:
... # first check to ensure the match is in the test_table
... if match in test_table:
... # ok, I know it is here, so get the index
... i = test_table.index(match)
... v = test_table[i]
... print(f'index [{i}] has value [{v}]')
...
index [3] has value [A]
index [3] has value [A]
Edit:
Here is some more info on the .index function, and here is another link to a question that indicates your present error is related to memory corruption.

TypeError: 'str' object does not support item assignment (Python)

So this is what I'm trying to do:
input: ABCDEFG
Desired output:
***DEFG
A***EFG
AB***FG
ABC***G
ABCD***
and this is the code I wrote:
def loop(input):
output = input
for index in range(0, len(input)-3): #column length
output[index:index +2] = '***'
output[:index] = input[:index]
output[index+4:] = input[index+4:]
print output + '\n'
But I get the error: TypeError: 'str' object does not support item assignment
You cannot modify the contents of a string, you can only create a new string with the changes. So instead of the function above you'd want something like this
def loop(input):
for index in range(0, len(input)-3): #column length
output = input[:index] + '***' + input[index+4:]
print output
Strings are immutable. You can not change the characters in a string, but have to create a new string. If you want to use item assignment, you can transform it into a list, manipulate the list, then join it back to a string.
def loop(s):
for index in range(0, len(s) - 2):
output = list(s) # create list from string
output[index:index+3] = list('***') # replace sublist
print(''.join(output)) # join list to string and print
Or, just create a new string from slices of the old string combined with '***':
output = s[:index] + "***" + s[index+3:] # create new string directly
print(output) # print string
Also note that there seemed to be a few off-by-one errors in your code, and you should not use input as a variable name, as it shadows the builtin function of the same name.
In Python, strings are immutable - once they're created they can't be changed. That means that unlike a list you cannot assign to an index to change the string.
string = "Hello World"
string[0] # => "H" - getting is OK
string[0] = "J" # !!! ERROR !!! Can't assign to the string
In your case, I would make output a list: output = list(input) and then turn it back into a string when you're finished: return "".join(output)
In python you can't assign values to specific indexes in a string array, you instead will probably want to you concatenation. Something like:
for index in range(0, len(input)-3):
output = input[:index]
output += "***"
output += input[index+4:]
You're going to want to watch the bounds though. Right now at the end of the loop index+4 will be too large and cause an error.
strings are immutable so don't support assignment like a list, you could use str.join concatenating slices of your string together creating a new string each iteration:
def loop(inp):
return "\n".join([inp[:i]+"***"+inp[i+3:] for i in range(len(inp)-2)])
inp[:i] will get the first slice which for the first iteration will be an empty string then moving another character across your string each iteration, the inp[i+3:] will get a slice starting from the current index i plus three indexes over also moving across the string one char at a time, you then just need to concat both slices to your *** string.
In [3]: print(loop("ABCDEFG"))
***DEFG
A***EFG
AB***FG
ABC***G
ABCD***

'int' object and 'float' object not callable error

I have a post request returning a list: [u'2']
I am trying to extract the number and turn it into and integer but I keep getting either 'float' object not callable or 'int' object not callable.
Here is what I have tried so far:
speed = [u'2']
strSpeed = speed[3]
intSpeed = int(strSpeed)
and
strSpeed = speed[3]
intSpeed = float(strSpeed)
and
strSpeed = speed[3]
intSpeed = int(float(strSpeed))
It seems that I can do:
print float(strSpeed)
but I can't return it.
Any ideas?
You have a list of Unicode strings:
>>> speed
[u'2']
Obtain the first item from the list, it's a Unicode string:
>>> speed[0]
u'2'
Convert this string to an integer:
>>> int(speed[0])
2
Here you are.
Your speed variable has only a single item, so you can only access index [0]
>>> int(speed[0])
2
>>> speed[0]
'2'
The u is a prefix to declare a unicode string literal. So speed is just a list with a single unicode string.
Not sure exactly what you are trying to do but if you have a list of string items and you want to extract and convert to integters or floats, you could do the following:
stringlist = ["1", "2", "3.2"]
intlistitem = int(stringlist[0])
print(intlistitem)
floatlistitem = float(stringlist[2])
print(floatlistitem)

String operations not working on python strings

I am using xlrd to read xls cell into a string, after which none of the string functions work on that string.
attribute_name = str(worksheet.cell_value(row,col))
attribute_name.strip()
attribute_name.lower()
print len(attribute_name)
if(len(attribute_name) > 8):
print 'value' + str(ord(attribute_name[8]))
print 'attributename:'+attribute_name+':'
prints :
9
value32
attributename:TSA01_HE :
9
value32
attributename:TSA02_HE :
I am mainly interested in getting rid of the whitespace at the end of the attribute name. Am I missing anything obvious ? I have tried replace etc but as you can see, even .lower() doesnt work.
$ python --version
Python 2.7.5
strip and lower do not work in place; they return the changed value. So you should assign their result to the old variable.
attribute_name = attribute_name.strip().lower()
Methods like str.XXX always return new strings instead of edit the original string. This is because strings are immutables in python. Likewise, operators on string like += rebinds the variable to a new string as well:
In [755]: s='a'
In [756]: id(s)
Out[756]: 30887376
In [757]: s+='bc' #same as s=s+'bc'
In [758]: id(s) #identity of the variable has been changed
Out[758]: 301145192
So if you wish your operation on a string to take effect, always remember to assign the result back with =.
Other immutables like ints, floats, tuples, frozensets works the same as strs. E.g., you won't expect i=3; i.__add__(10) makes i==13.
Take care that both strip() and lower() do not modify the string you apply them on; you should therefore do attribute_name = attribute_name.strip().lower().
Example:
>>> a = ' A '
>>> a.strip().lower()
'a'
>>> a
' A '

Categories