i need to do some processing on a string that requires temporarily putting its contents into a list. then it needs to be made back into a string. but there are a bunch of string types that could be involved. i want to handle them all. what is the best way to convert a list to a string and have it be the same type as the original string (still have a reference to it if that helps).
(Sep-03-2018, 02:25 PM)Skaperen Wrote: [ -> ]but there are a bunch of string types that could be involved. i want to handle them all
Can you describe these string types?
str, unicode, bytes, bytearray
The 'to_list()' part is easy
def to_list(item):
return item.split()
For the 'from_list()' part, you can use this for non empty lists (works for python >= 2.7)
_joinchar = dict([(type(k), k) for k in (' ', b' ', u' ', bytearray(b' '))])
def from_list(items):
return _joinchar[type(items[0])].join(items)
For the empty list, you need the target type...
i was playing around with ...
original_string[0:0].join(temp_list)
... or ...
temp_list[0][0:0].join(temp_list)
... under the assumption that the items in the list were strings of the same type. for some things, like slicing in-place, this should be enough. for others, i might need to make the items in the list be some common form, such as only string, or as only int. it looks like in this case i might need to have blocks of code for various types.
One thing to consider is that with [0:0]
, you'll join with the empty string instead of a space character. That's why I introduced the _joinchar
dictionary.
There is still a missing feature in my code above: it doesn't handle the case of user defined subclasses of the builtin string types. A generic function should solve this issue, that is to say code from_list()
with functools.singledispatch()
.
if i have split a string of length 17 into a list of length 17, one character per item, then i would want an empty string as the base for a .join(). the [0:0] was to get that in the same type.
Don't know what you are doing.
class ListString:
def __init__(self, string):
self.type = type(string)
self.string = list(string)
def __getitem__(self, index):
return self.string[index]
def __setitem__(self, index, value):
self.string[index] = value
def __len__(self):
return len(self.string)
def __bool__(self):
return len(self) > 0
def __str__(self):
return str(self.string)
def get_string(self):
if self.type == str:
return ''.join(self.string)
return self.type(self.string)
a = ListString('string')
print(a)
print(a.get_string())
a = ListString(b'bytes')
print(a)
print(a.get_string())
a = ListString(bytearray(b'bytearray'))
print(a)
print(a.get_string())
i was going to do some slicing of a string to modify it, which cannot be done directly since strings are immutable. i did not want to change it to a bytearray since, some day, maybe soon, there might be some unicode in there. lists seem to be the logical choice. convert it to a list of single characters, then do the slicing i need with other lists that were converted from strings, then convert back to a string.
(Sep-06-2018, 02:43 AM)Skaperen Wrote: [ -> ]i did not want to change it to a bytearray since, some day, maybe soon, there might be some unicode in there.
You can use
array.array()
. The following code works in python 3 and 2
>>> from array import array
>>> s = array('u', u'Hello World')
>>> s[6:] = array('u', u'Skaperen')
>>> s
array('u', 'Hello Skaperen')