ast.literal_eval - loop over string elements in a list - python

Goal: I want to extract longlat tuples in the map key from a request.POST below.
<QueryDict: {'map': ['(38.70053557156445, 149.81571853160858)', '(38.70060091643143, 149.8153966665268)'], 'csrfmiddlewaretoken': ###}>
Problem: I used ast.literal_eval to extract the tuples but somehow only 2nd tuple is returned.
markers = request.POST
position = ast.literal_eval(markers['map'])
I also tried looping over map with but this is giving me SyntaxError: unexpected EOF while parsing on tuple parentheses.
for idx, val in enumerate(markers['map']):
position = ast.literal_eval(markers['map'][idx])
Finally, I tried list(map(ast.literal_eval, markers['map'])), but this returns the same SyntaxError as above.

It’s common for query strings to be used to represent both keys with single values and keys with multiple values, so Django’s QueryDict requires that you specify the type you’re looking for:
position = list(map(ast.literal_eval, markers.getlist('map')))

Related

string indices must be integers json

i have a json data https://steamcommunity.com/id/RednelssGames/inventory/json/730/2
need get names of all the items
r = requests.get('https://steamcommunity.com/id/RednelssGames/inventory/json/730/2')
if r.json()['success'] == True:
for rows in r.json()['rgDescriptions']:
print(rows['market_hash_name'])
getting error string indices must be integers
Change the for-loop as follows:
for rows in r.json()['rgDescriptions'].values():
print(rows['market_hash_name'])
By iterating over a dictionary like you did, you get the keys and not the values (rows). If you want to iterate over the values, you have to iterate over the return value of dict.values().
From the link you provided:
"rgDescriptions":{"4291220570_302028390":
rgDescriptions doesn't return an array, but an object (a dictionary, in this case) (notice the opening curly brace ({) rather than a regular square brace ([)).
By using for rows in r.json()['rgDescriptions']: you end up iterating over the dictionary's keys. The first key of the dictionary seems to be "4291220570_302028390", which is a string.
so when you do print(rows['market_hash_name']), you're attempting to access the 'market_hash_name' "index" of your rows object, but rows is actually a string, so it doesn't work.

Python - get elements from list

From a python function, I get the following output:
['(0.412169, mississippi)']
The type indicates that it is a list. I want to extract the values from the list and save it as separate elements. I tried various functions to convert list to tuple, list to str, extracting the element by Index from the tuple or str, nothing worked out. When I try to extract the element by index, I either get '(' for the first element index 0, or when I try to extract through a iterator function, I get all the values split up like the full data set as a string.
How do I get values separately.
You can iterate over your data, remove the parentheses using slicing and split the string by comma to create a list, which will be appended to your output payload:
data = ['(0.412169, mississippi)', '(0.412180, NY)']
extracted_values = []
for d in data:
extracted_values += d[1:-1].split(",")
print(extracted_values)
# output: ['0.412169', ' mississippi', '0.412180', ' NY']
Your list content a string, not a list.
If you want to extract the content of a string, use the "eval" statement
my_tuple = eval("(0.412169, 'mississippi')")
Note that the "eval" function can be dangerous, because if your string content python code, it could be executed.

Pymongo find using $in with a list

The folowing expression works fine, returning the values that match the values list:
[...].find({"FieldName":{"$in":["Value1", "Value2", "Value3"]}})
But i have the list of values in a list object, like this:
valuesList = list()
valuesList.append("Value1")
valuesList.append("Value2")
valuesList.append("Value3")
But using the list object, a get no results:
[...].find({"FieldName":{"$in":[valuesList]}})
I Have also tried expanding the list in a formated string, like this:
strList = ', '.join(valuesList)
[...].find({"FieldName":{"$in":[strList]}})
but also, no results.
Note: If i force the list to have only one value, it works. Only when multiple values are suplied, the result is blank.
Any ideas on how to use "$in" in pymongo with a list of values in a list object?
I believe your problem is the fact that you have a list inside of a list.
Instead of:
[...].find({"FieldName":{"$in":[valuesList]}})
Try:
[...].find({"FieldName":{"$in":valuesList}})

Converting a string to dictionary in python

I have the following string :
str = "{application.root.category.id:2}"
I would like to convert the above to a dictionary data type in python as in :
dict = {application.root.category.id:2}
I tried using eval() and this is the error I got:
AttributeError: java package 'application' has no attribute "root"
My current python is of <2.3 and I cannot update the python to >2.3 .
Any solutions ?
Python dictionaries have keys that needn't be strings; therefore, when you write {a: b} you need the quotation marks around a if it's meant to be a string. ({1:2}, for instance, maps the integer 1 to the integer 2.)
So you can't just pass something of the sort you have to eval. You'll need to parse it yourself. (Or, if it happens to be easier, change whatever generates it to put quotation marks around the keys.)
Exactly how to parse it depends on what your dictionaries might actually look like; for instance, can the values themselves be dictionaries, or are they always numbers, or what? Here's a simple and probably too crude approach:
contents = str[1:-1] # strip off leading { and trailing }
items = contents.split(',') # each individual item looks like key:value
pairs = [item.split(':',1) for item in items] # ("key","value"), both strings
d = dict((k,eval(v)) for (k,v) in pairs) # evaluate values but not strings
First, 'dict' is the type name so not good for the variable name.
The following, does precisely as you asked...
a_dict = dict([str.strip('{}').split(":"),])
But if, as I expect, you want to add more mappings to the dictionary, a different approach is required.
Suppose I have a string
str='{1:0,2:3,3:4}'
str=str.split('{}')
mydict={}
for every in str1.split(','):
z=every.split(':')
z1=[]
for every in z:
z1.append(int(every))
for k in z1:
mydict[z1[0]]=z1[1]
output:
mydict
{1: 0, 2: 1, 3: 4}

ValueError: need more than 1 value to unpack

I want to change the contents in a list of tuples, returned by a findall() function. And I am not sure whether I could change the elements from string to integer like this. And the error always shows that I need more than 1 value.
Ntuple=[]
match = re.findall(r'AnswerCount="(\d+)"\s*CommentCount="(\d+)"', x)
print match
for tuples in match:
for posts, comments in tuples:
posts, comments = int(posts), (int(posts)+int(comments)) ## <- error
print match
The problem is in the line for posts, comments in tuples:. Here tuples is actually a single tuple containing two strings, so there is no need to iterate over it. You probably want something like:
matches = re.findall(...)
for posts, comments in matches:
....
match is a list of tuples. The correct way of iterating over it is:
matches = re.findall(r'AnswerCount="(\d+)"\s*CommentCount="(\d+)"', x)
for posts, comments in matches:
posts, comments = int(posts), (int(posts)+int(comments))
The conversion from string to integer is fine.

Categories

Resources