I have a string that looks identical to a list, let's say:
'[万福广场西,凰花苑]'
I would like to convert it into something like this:
['万福广场西','凰花苑']
I used eval() and ast.literal_eval() but got error as following:
y=eval('[万福广场西,凰花苑]')
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-117-0aadbead218c> in <module>()
----> 1 y=eval('[万福广场西,凰花苑]')
<string> in <module>()
NameError: name '万福广场西' is not defined
when using ast.literal_eval(), I got this error ValueError: malformed node or string: <_ast.Name object at 0x000002A67FFA5CC0>
Try Something like
my_list = '[万福广场西,凰花苑]'[1:-1].split(",")
It will return you an list -- ['万福广场西', '凰花苑']
You can check it as -- type(my_list) #<class 'list'>
Use strip and split
>>> '[万福广场西,凰花苑]'.strip('[]').split(",")
['万福广场西', '凰花苑']
eval() will consider the given string as python code and return the result. So as per your string, the python code will something like this [万福广场西,凰花苑] which means two variable 万福广场西 and 凰花苑 are in a list.
If you want it to be evaluated as a list of strings you need to bound both strings with double quotes (") such as
'["万福广场西","凰花苑"]'.
When you subject this string to eval(), the output would be,
['万福广场西', '凰花苑']
If you want this to happen dynamically, you need to use split and join functions like,
''.join(list('[万福广场西,凰花苑]')[1:-1]).split(',')
which first makes the list of strings given by
list('[万福广场西,凰花苑]')[1:-1] # O/P ['万', '福', '广', '场', '西', ',', '凰', '花', '苑']
then joins all the strings as
''.join(['万', '福', '广', '场', '西', ',', '凰', '花', '苑']) # O/P 万福广场西,凰花苑
and splits the string by comma (,) to create your desired output.
'万福广场西,凰花苑'.split(',') # O/P ['万福广场西', '凰花苑']
Hope you have got what you were searching for. Feel free to comment in case of any clarifications required.
The content of your string isn't actually a valid list of literals because the literals are lacking the necessary quotes, so you can't parse it with eval() or ast.literal_eval().
Instead, you can use regular expression to parse the string into a list:
import re
print(re.findall(r'[^\[\],]+', '[万福广场西,凰花苑]'))
This outputs:
['万福广场西', '凰花苑']
Related
Given a string. Replace in this string all the numbers 1 by the word one.
Example input:
1+1=2
wished output:
one+one=2
I tried the following but does not work with an int:
s=input()
print(s.replace(1,"one"))
How can I replace an integer?
You got a TypeError like below.
Use '1' of type str as first argument (string instead number) because you want to work with strings and replace parts of the string s.
Try in Python console like:
>>> s = '1+1=2'
>>> print(s.replace(1,"one"))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: replace() argument 1 must be str, not int
>>> print(s.replace('1',"one"))
one+one=2
or simply use the string-conversion method str():
s.replace(str(1), 'one')
Whilst you could simply use a replace(), I would suggest instead using a python dictionary. Defining each number to a word, that would then switch. Like this.
conversion = {
1: 'one',
2: 'two'
}
You can then use this like a dictionary
print(conversion[1]) # "one"
print(conversion[2]) # "two"
This simply makes your code more adaptable, in case you want to convert some numbers and not all. Just an alternative option to consider.
User is giving list as input [1,2,3,4]:
a = input()
It is taking this as str.
I want to get this data into local list b.
b = a.strip('][').split(', ')
print(b)
Output: ['1,2,3,4']
How to get list individually not a single entity?
You should do .split(',') instead of .split(', ')
You can use ast.literal_eval to do so.
import ast
a = input()
b = ast.literal_eval(a)
print(b)
# output
[1, 2, 3, 4]
From the docs:
Safely evaluate an expression node or a string containing a Python
literal or container display. The string or node provided may only
consist of the following Python literal structures: strings, bytes,
numbers, tuples, lists, dicts, sets, booleans, None and Ellipsis.
This can be used for safely evaluating strings containing Python
values from untrusted sources without the need to parse the values
oneself. It is not capable of evaluating arbitrarily complex
expressions, for example involving operators or indexing.
the problem is that in the line:
b = a.strip('][').split(', ')
you used ', ' with whitespace instead of ',' without whitespace
because your input does not have any spaces as shown below:
user is giving list as input [1,2,3,4]
ast.literal_eval(a) gets the string input as a list datatype, which can be converted into a list of individual strings with map:
import ast
b = list(map(str,ast.literal_eval(a)))
['1', '2', '3', '4']
When I'm splitting a string "abac" I'm getting undesired results.
Example
print("abac".split("a"))
Why does it print:
['', 'b', 'c']
instead of
['b', 'c']
Can anyone explain this behavior and guide me on how to get my desired output?
Thanks in advance.
As #DeepSpace pointed out (referring to the docs)
If sep is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, '1,,2'.split(',') returns ['1', '', '2']).
Therefore I'd suggest using a better delimiter such as a comma , or if this is the formatting you're stuck with then you could just use the builtin filter() function as suggested in this answer, this will remove any "empty" strings if passed None as the function.
sample = 'abac'
filtered_sample = filter(None, sample.split('a'))
print(filtered_sample)
#['b', 'c']
When you split a string in python you keep everything between your delimiters (even when it's an empty string!)
For example, if you had a list of letters separated by commas:
>>> "a,b,c,d".split(',')
['a','b','c','d']
If your list had some missing values you might leave the space in between the commas blank:
>>> "a,b,,d".split(',')
['a','b','','d']
The start and end of the string act as delimiters themselves, so if you have a leading or trailing delimiter you will also get this "empty string" sliced out of your main string:
>>> "a,b,c,d,,".split(',')
['a','b','c','d','','']
>>> ",a,b,c,d".split(',')
['','a','b','c','d']
If you want to get rid of any empty strings in your output, you can use the filter function.
If instead you just want to get rid of this behavior near the edges of your main string, you can strip the delimiters off first:
>>> ",,a,b,c,d".strip(',')
"a,b,c,d"
>>> ",,a,b,c,d".strip(',').split(',')
['a','b','c','d']
In your example, "a" is what's called a delimiter. It acts as a boundary between the characters before it and after it. So, when you call split, it gets the characters before "a" and after "a" and inserts it into the list. Since there's nothing in front of the first "a" in the string "abac", it returns an empty string and inserts it into the list.
split will return the characters between the delimiters you specify (or between an end of the string and a delimiter), even if there aren't any, in which case it will return an empty string. (See the documentation for more information.)
In this case, if you don't want any empty strings in the output, you can use filter to remove them:
list(filter(lambda s: len(s) > 0, "abac".split("a"))
I have a string opening with { and closing with }. This brackets are always at first and at last and must appear, they can not appear in the middle. as following:
{-4,10746,.....,205}
{-3,105756}
what is the most efficient way to remove the brackets to receive:
-4,10746,.....,205
-3,105756
s[1:-1] # skip the first and last character
You can also use replace method.
In [1]: a = 'hello world'
In [3]: a.replace('l','')
Out[3]: 'heo word'
Since you were not clear there are two possibilities it may be a string or a set
If it is a set this might work:
a= {-4, 205, 10746}
",".join([str(s) for s in a])
output='10746,-4,205'
If it is a string this will work:
a= '{-4, 205, 10746}'
a.replace("{","").replace("}","")
output= '-4, 205, 10746'
Since there is no order in set the output is that way
Here's a rather roundabout way of doing exactly what you need:
l = {-3,105756}
new_l = []
for ch in l:
if ch!='{' and ch!= '}':
new_l.append(ch)
for i,val in enumerate(new_l):
length = len(new_l)
if(i==length-1):
print str(val)
else:
print str(val)+',',
I'm sure there are numerous single line codes to give you what you want, but this is kind of what goes on in the background, and will also remove the braces irrespective of their positions in the input string.
Just a side note, answer by #dlask is good to solve your issue.
But if what you really want is to convert that string (that looks like a set) to a set object (or some other data structure) , you can also use ast.literal_eval() function -
>>> import ast
>>> s = '{-3,105756}'
>>> sset = ast.literal_eval(s)
>>> sset
{105756, -3}
>>> type(sset)
<class 'set'>
From documentation -
ast.literal_eval(node_or_string)
Safely evaluate an expression node or a Unicode or Latin-1 encoded string containing a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.
The safest way would be to strip:
'{-4, 205, 10746}'.strip("{}")
Have a set of string as follows
text:u'MUC-EC-099_SC-Memory-01_TC-25'
text:u'MUC-EC-099_SC-Memory-01_TC-26'
text:u'MUC-EC-099_SC-Memory-01_TC-27'
These data i have extracted from a Xls file and converted to string,
now i have to Extract data which is inside single quotes and put them in a list.
expecting output like
[MUC-EC-099_SC-Memory-01_TC-25, MUC-EC-099_SC-Memory-01_TC-26,MUC-EC-099_SC-Memory-01_TC-27]
Thanks in advance.
Use re.findall:
>>> import re
>>> strs = """text:u'MUC-EC-099_SC-Memory-01_TC-25'
text:u'MUC-EC-099_SC-Memory-01_TC-26'
text:u'MUC-EC-099_SC-Memory-01_TC-27'"""
>>> re.findall(r"'(.*?)'", strs, re.DOTALL)
['MUC-EC-099_SC-Memory-01_TC-25',
'MUC-EC-099_SC-Memory-01_TC-26',
'MUC-EC-099_SC-Memory-01_TC-27'
]
You can use the following expression:
(?<=')[^']+(?=')
This matches zero or more characters that are not ' which are enclosed between ' and '.
Python Code:
quoted = re.compile("(?<=')[^']+(?=')")
for value in quoted.findall(str(row[1])):
i.append(value)
print i
That text: prefix seems a little familiar. Are you using xlrd to extract it? In that case, the reason you have the prefix is because you're getting the wrapped Cell object, not the value in the cell. For example, I think you're doing something like
>>> sheet.cell(2,2)
number:4.0
>>> sheet.cell(3,3)
text:u'C'
To get the unwrapped object, use .value:
>>> sheet.cell(3,3).value
u'C'
(Remember that the u here is simply telling you the string is unicode; it's not a problem.)