I'm trying to convert a list of lists passed as string to nested list in python-3.7.5 and I'm missing something. I tried ast but it seems to be throwing an encoding error.
Example:
#!/usr/bin/env python
import ast
sample="[1abcd245,2bcdasdf,3jakdshfkh234234],[234asdfmnkk234]"
print(ast.literal_eval(sample))
ERROR:
return compile(source, filename, mode, PyCF_ONLY_AST)
File "<unknown>", line 1
[1abcd245,2bcdasdf,3jakdshfkh234234],[234asdfmnkk234]
Required output:
[[1abcd245,2bcdasdf,3jakdshfkh234234],[234asdfmnkk234]]
Any suggestions?
You may use the eval() function here, after making two changes to your starting string:
Wrap each list item in double quotes
Wrap the entire input in [...] to make it a formal 2D list
sample = "[1abcd245,2bcdasdf,3jakdshfkh234234],[234asdfmnkk234]"
sample = '[' + re.sub(r'(\w+)', r'"\1"', sample) + ']'
list = eval(sample)
print(list)
This prints:
[['1abcd245', '2bcdasdf', '3jakdshfkh234234'], ['234asdfmnkk234']]
I think the issue is that literal_eval is unable to parse the strings within the sample you provide. I was able to get the output you wanted by adding a triple quote to surround the sample string, adding quotes to each string within the lists and adding an extra set of brackets:
import ast
sample="""[["1abcd245","2bcdasdf","3jakdshfkh234234"],["234asdfmnkk234"]]"""
print(ast.literal_eval(sample))
In the case you cannot change the input I would recommend using the json library:
import json
json.loads(sample)
Which on my machine gets the desired result!
you can try this:
sample="[1abcd245,2bcdasdf,3jakdshfkh234234],[234asdfmnkk234]"
l1 = []
for item in sample.split(","):
if item.startswith('['):
l1.append([])
l1[-1].append(item[1:])
elif item.endswith(']'):
l1[-1].append(item[:-2])
else:
l1[-1].append(item)
print(l1)
Related
I have a string in the form of
[[sourceId:111, clientId:12345, clientName:testclient, module:test,source:Request, userName:Michelle Jackson],[sourceId:112, clientId:1233, clientName:testclient2, module:test, source:Request, userName:Michelle Jackson]]
How do I convert it into a valid python list of json ?
Although I never recommend doing this, here's the code
import re
arr = []
for x in s.split('],['):
kv = re.sub('\[|\]', '', x)
arr.append(dict(kvi.split(':') for kvi in kv.split(',')))
NOTE: If the string is system generated, it's better to get it in JSON format in the first place.
I have:
"[15765,22832,15289,15016,15017]"
I want:
[15765,22832,15289,15016,15017]
What should I do to convert this string to list?
P.S. Post was edited without my permission and it lost important part. The type of line that looks like list is 'bytes'. This is not string.
P.S. №2. My initial code was:
import urllib.request, re
f = urllib.request.urlopen("http://www.finam.ru/cache/icharts/icharts.js")
lines = f.readlines()
for line in lines:
m = re.match('var\s+(\w+)\s*=\s*\[\\s*(.+)\s*\]\;', line.decode('windows-1251'))
if m is not None:
varname = m.group(1)
if varname == "aEmitentIds":
aEmitentIds = line #its type is 'bytes', not 'string'
I need to get list from line
line from web page looks like
[15765, 22832, 15289, 15016, 15017]
Assuming s is your string, you can just use split and then cast each number to integer:
s = [int(number) for number in s[1:-1].split(',')]
For detailed information about split function:
Python3 split documentation
What you have is a stringified list. You could use a json parser to parse that information into the corresponding list
import json
test_str = "[15765,22832,15289,15016,15017]"
l = json.loads(test_str) # List that you need.
Or another way to do this would be to use ast
import ast
test_str = "[15765,22832,15289,15016,15017]"
data = ast.literal_eval(test_str)
The result is
[15765, 22832, 15289, 15016, 15017]
To understand why using eval() is bad practice you could refer to this answer
You can also use regex to pull out numeric values from the string as follows:
import re
lst = "[15765,22832,15289,15016,15017]"
lst = [int(number) for number in re.findall('\d+',lst)]
Output of the above code is,
[15765, 22832, 15289, 15016, 15017]
I want to split this python list (originalList):
['"car_type":"STANDARD","price":725842',
'"car_type":"LUXURY","price":565853',
'"car_type":"PEOPLE_CARRIER","price":239081',
'"car_type":"LUXURY_PEOPLE_CARRIER","price":661624',
'"car_type":"MINIBUS","price":654172']
to give me this list (pricesList):
[725842, 565853, 239081, 661624, 654172]
I tried this line of code below to split the list named originalList:
pricesList = [i.split("price:")[0] for i in originalList]
The outcome is a list with the same number of elements, but each element contains the car_type only, in short the splitting has removed everything to the left of the delimiter. How can I change my code above or even replace to obtain in the new list elements with the values to the left of the delimiter and everything to the right removed?
You forget the double-quotes " that are part of your delimiter, then pick the wrong index (0) which is before the split, and finally, you do not cast to int. You can do the following to get the desired output:
>>> [int(i.split('"price":')[-1]) for i in originalList]
[725842, 565853, 239081, 661624, 654172]
schwobaseggl answer is good, here is a possible alternative using json library (I guess original list comes from json processing)
import json
list(map(lambda x:json.loads('{'+x+'}')['price'],originalList))
You can try:
import json
n = ['"car_type":"STANDARD","price":725842',
'"car_type":"LUXURY","price":565853',
'"car_type":"PEOPLE_CARRIER","price":239081',
'"car_type":"LUXURY_PEOPLE_CARRIER","price":661624',
'"car_type":"MINIBUS","price":654172']
print [json.loads("{"+str(i)+"}")["price"] for i in n]
Another way of doing it:
pricesList = [int(originalList[i].split(",")[1].split(":")[1]) for i in range(0,len(l1))]
Solution
If you change to .split(':') you can just take the [-1] item, that will represent the numbers at the end
lista = [
'"car_type":"STANDARD","price":725842',
'"car_type":"LUXURY","price":565853',
'"car_type":"PEOPLE_CARRIER","price":239081',
'"car_type":"LUXURY_PEOPLE_CARRIER","price":661624',
'"car_type":"MINIBUS","price":654172'
]
new_lista = []
for i in range(len(lista)):
lista[i] = lista[i].split(':')
new_lista.append(lista[i][-1])
print(new_lista)
Output
(xenial)vash#localhost:~/python$ python3.7 split.py
['725842', '565853', '239081', '661624', '654172']
i have some problem to strip '[' at my string (read from file).
code
data = open(Koorpath1,'r')
for x in data:
print(x)
print(x.strip('['))
result
[["0.9986130595207214","26.41608428955078"],["39.44521713256836","250.2412109375"],["112.84327697753906","120.34269714355469"],["260.63800048828125","15.424667358398438"],["273.6199645996094","249.74160766601562"]]
"0.9986130595207214","26.41608428955078"],["39.44521713256836","250.2412109375"],["112.84327697753906","120.34269714355469"],["260.63800048828125","15.424667358398438"],["273.6199645996094","249.74160766601562"]]
Desired output :
"0.9986130595207214","26.41608428955078","39.44521713256836","250.2412109375","112.84327697753906","120.34269714355469","260.63800048828125","15.424667358398438","273.6199645996094","249.74160766601562"
Thanks
It strips the first two '[', it seems you have one long string, you have to split it first.
datalist = data.split[',']
for x in datalist:
# code here
If you don't want to split it and have it all in one string you need replace not strip (strip only works at the end and the beginning.
data = data.replace('[','')
If the data is JSON, then parse it into a Python list and treat it from there:
from itertools import chain
import json
nums = json.loads(x)
print(','.join('"%s"' % num for num in chain.from_iterable(nums)))
chain.from_iterable helps you "flatten" the list of lists and join concatenates everything into one long output.
I set up a dictionary, and filled it from a file, like so:
filedusers = {} # cheap way to keep track of users, not for production
FILE = open(r"G:\School\CS442\users.txt", "r")
filedusers = ast.literal_eval("\"{" + FILE.readline().strip() + "}\"")
FILE.close()
then later I did a test on it, like this:
if not filedusers.get(words[0]):
where words[0] is a string for a username, but I get the following error:
'str' object has no attribute 'get'
but I verified already that after the FILE.close() I had a dictionary, and it had the correct values in it.
Any idea what's going on?
literal_eval takes a string, and converts it into a python object. So, the following is true...
ast.literal_eval('{"a" : 1}')
>> {'a' : 1}
However, you are adding in some quotations that aren't needed. If your file simply contained an empty dictionary ({}), then the string you create would look like this...
ast.literal_eval('"{}"') # The quotes that are here make it return the string "{}"
>> '{}'
So, the solution would be to change the line to...
ast.literal_eval("{" + FILE.readline().strip() + "}")
...or...
ast.literal_eval(FILE.readline().strip())
..depending on your file layout. Otherwise, literal_eval sees your string as an ACTUAL string because of the quotes.
>>> import ast
>>> username = "asd: '123'"
>>> filedusers = ast.literal_eval("\"{" + username + "}\"")
>>> print filedusers, type(filedusers)
{asd} <type 'str'>
You don't have a dictionary, it just looks like one. You have a string.
Python is dynamically typed: it does not require you to define variables as a specific type. And it lets you define variables implicitly. What you are doing is defining filedusers as a dictionary, and then redefining it as a string by assigning the result of ast.literal_eval to it.
EDIT: You need to remove those quotes. ast.literal_eval('"{}"') evaluates to a string. ast.literal_eval('{}') evaluates to a dictionary.