I WANTED OUTPUT SORTED BY [A,B,C,D,E] IN THE LIST
A =['12,Boring Stuff with Python Programming,D,692617,4.6,70508',
'10,Complete C# 2D,A,364934,4.6,78989',
'5,Java Developers,B,502572,4.6,123798',
'15,Learn Python Programming Masterclass,C,240790,4.5,58677',
'3,Machine Learning A-Z,E,692812,4.5,132228',]
def order(string):
v= []
for i in string:
m = i.split(",")
v.append(m[1])
return v
print(sorted(A,key=order))
WHEN I I USE 'M[0]', IT SORTED WITH [ 5,3,10,12,15 ] BUT WHEN USING 'M[1]' THE ERROR SHOW
Traceback (most recent call last):
File "ts.py", line 82, in <module>
print(sorted(A,key=order))
File "ts.py", line 80, in order
v.append(m[1])
IndexError: list index out of range
Assuming the letters [A B C D E] always fall in the third item, you could do::
>>> print(sorted(A, key=lambda x: x.split(',')[2]))
['10,Complete C# 2D,A,364934,4.6,78989',
'5,Java Developers,B,502572,4.6,123798',
'15,Learn Python Programming Masterclass,C,240790,4.5,58677',
'12,Boring Stuff with Python Programming,D,692617,4.6,70508',
'3,Machine Learning A-Z,E,692812,4.5,132228']
Notice the key function does not take the whole list, but it takes one item from the list (the string), and returns the part of that string that should be used as they key for comparison. In this case, the third item counting by commas. Without key it defaults to using the whole item (the string) as they key, functionally speaking the identity function.
I have a string
str = "Name John"
I want to change it to a dictionary.
{"Name":"John"}
How do I achieve this?
I Have tried using comprehension but I get an error.
str = "Arjun 23344"
Name = {str.split()}
Error
Traceback (most recent call last):
File "/home/daphney/Python/AGame.py", line 2, in <module>
Name = {x.split()}
TypeError: unhashable type: 'list'
You can split:
my_dict = {str.split(" ")[0]:str.split(" ")[1]}
Note: If you have, say, Name John Smith and want the dict to be Name:Smith, then you can just change the [1] to [-1] to get the last indexed item.
You can create a dictionary using dict function by providing list of [key,value] lists (or (key,value) tuples):
my_str = "Arjun 23344"
Name = dict([my_str.split()])
print(Name) # output: {'Arjun': '23344'}
Name = dict([str.split()])
This would only work if your string always splits into exactly two words. This works because the split call returns a list of two elements, which is then stored inside a containing list, and passed to the dict constructor. The latter can work properly with a sequence (list or other) of pairs (lists or other).
This works in this particular case, but is not robust or portable.
As there are only two strings in your variable.
string = "Name Shivank"
k,v = string.split()
d = dict()
d[k] = v
print(d) #output: {'Name':'Shivank'}
you can provide a second parameter to the split function to limit the number of separations (to 1 in this case):
dict([string.split(" ",1)])
I'm new to Python and trying to figure out the best way to parse the values of a JSON object into an array, using a list comprehension.
Here is my code - I'm querying the publicly available iNaturalist API and would like to take the JSON object that it returns, so that I take specific parts of the JSON object into a bumpy array:
import json
import urllib2
#Set Observations URL request for Resplendent Quetzal of Costa Rica
query = urllib2.urlopen("http://api.inaturalist.org/v1/observations?place_id=6924&taxon_id=20856&per_page=200&order=desc&order_by=created_at")
obSet = json.load(query)
#Print out Lat Long of observation
n = obSet['total_results']
for i in range(n) :
print obSet['results'][i]['location']
This all works fine and gives the following output:
9.5142456535,-83.8011438905
10.2335478381,-84.8517773638
10.3358965682,-84.9964271008
10.3744851815,-84.9871494128
10.2468720343,-84.9298072822
...
What I'd like to do next is replace the for loop with a list comprehension, and store the location value in a tuple. I'm struggling with the syntax in that I'm guessing it's something like this:
[(long,lat) for i in range(n) for (long,lat) in obSet['results'][i]['location']]
But this doesn't work...thanks for any help.
obSet['results'] is a list, no need to use range to iterate over it:
for item in obSet['results']:
print(item['location'])
To make this into list comprehension you can write:
[item['location'] for item in obSet['results']]
But, each location is coded as a string, instead of list or tuple of floats. To get it to the proper format, use
[tuple(float(coord) for coord in item['location'].split(','))
for item in obSet['results']]
That is, split the item['location'] string into parts using , as the delimiter, then convert each part into a float, and make a tuple of these float coordinates.
The direct translation of your code into a list comprehension is:
positions = [obSet['results'][i]['location'] for i in range(obSet['total_results'])]
The obSet['total_results'] is informative but not needed, you could just loop over obSet['results'] directly and use each resulting dictionary:
positions = [res['location'] for res in obSet['results']]
Now you have a list of strings however, as each 'location' is still the long,lat formatted string you printed before.
Split that string and convert the result into a sequence of floats:
positions = [map(float, res['location'].split(',')) for res in obSet['results']]
Now you have a list of lists with floating point values:
>>> [map(float, res['location'].split(',')) for res in obSet['results']]
[[9.5142456535, -83.8011438905], [10.2335478381, -84.8517773638], [10.3358965682, -84.9964271008], [10.3744851815, -84.9871494128], [10.2468720343, -84.9298072822], [10.3456659939, -84.9451804822], [10.3611732346, -84.9450302597], [10.3174360636, -84.8798676791], [10.325110706, -84.939710318], [9.4098152454, -83.9255607577], [9.4907141714, -83.9240819199], [9.562637289, -83.8170178428], [9.4373885911, -83.8312881263], [9.4766746409, -83.8120952573], [10.2651190176, -84.6360466565], [9.6572995298, -83.8322965118], [9.6997991784, -83.9076919066], [9.6811177044, -83.8487647156], [9.7416717045, -83.929327673], [9.4885099275, -83.9583968683], [10.1233252667, -84.5751029683], [9.4411815757, -83.824401543], [9.4202687169, -83.9550344212], [9.4620656621, -83.665183105], [9.5861809119, -83.8358881552], [9.4508914243, -83.9054016165], [9.4798058284, -83.9362558497], [9.5970449879, -83.8969131893], [9.5855562829, -83.8354434596], [10.2366179555, -84.854847472], [9.718459702, -83.8910277016], [9.4424384874, -83.8880459793], [9.5535916157, -83.9578166199], [10.4124554163, -84.9796942349], [10.0476688795, -84.298227929], [10.2129436252, -84.8384097435], [10.2052632717, -84.6053701877], [10.3835784147, -84.8677930134], [9.6079669672, -83.9084281155], [10.3583643315, -84.8069762134], [10.3975986735, -84.9196996767], [10.2060835381, -84.9698814407], [10.3322929317, -84.8805587129], [9.4756504472, -83.963818143], [10.3997876964, -84.9127311339], [10.1777433853, -84.0673088686], [10.3346128571, -84.9306278215], [9.5193346195, -83.9404786293], [9.421538224, -83.7689452093], [9.430427837, -83.9532672942], [10.3243212895, -84.9653175843], [10.021698503, -83.885674888]]
If you must have tuples rather than lists, add a tuple() call:
positions = [tuple(map(float, res['location'].split(',')))
for res in obSet['results']]
The latter also makes sure the expression works in Python 3 (where map() returns an iterator, not a list); you'd otherwise have to use a nested list comprehension:
# produce a list of lists in Python 3
positions = [[float(p) for p in res['location'].split(',')] for res in obSet['results']]
Another way to get list of [long, lat] without list comprehension:
In [14]: map(lambda x: obSet['results'][x]['location'].split(','), range(obSet['total_results']))
Out[14]:
[[u'9.5142456535', u'-83.8011438905'],
[u'10.2335478381', u'-84.8517773638'],
[u'10.3358965682', u'-84.9964271008'],
[u'10.3744851815', u'-84.9871494128'],
...
If you would like list of tuples instead:
In [14]: map(lambda x: tuple(obSet['results'][x]['location'].split(',')), range(obSet['total_results']))
Out[14]:
[[u'9.5142456535', u'-83.8011438905'],
[u'10.2335478381', u'-84.8517773638'],
[u'10.3358965682', u'-84.9964271008'],
[u'10.3744851815', u'-84.9871494128'],
...
If you want to convert to floats too:
In [17]: map(lambda x: tuple(map(float, obSet['results'][x]['location'].split(','))), range(obSet['total_results']))
Out[17]:
[(9.5142456535, -83.8011438905),
(10.2335478381, -84.8517773638),
(10.3358965682, -84.9964271008),
(10.3744851815, -84.9871494128),
(10.2468720343, -84.9298072822),
(10.3456659939, -84.9451804822),
...
You can iterate over the list of results directly:
print([tuple(result['location'].split(',')) for result in obSet['results']])
>> [('9.5142456535', '-83.8011438905'), ('10.2335478381', '-84.8517773638'), ... ]
[tuple(obSet['results'][i]['location'].split(',')) for i in range(n)]
This will return a list of tuple, elements of the tuples are unicode.
If you want that the elements of tuples as floats, do the following:
[tuple(map(float,obSet['results'][i]['location'].split(','))) for i in range(n)]
To correct way to get a list of tuples using list comprehensions would be:
def to_tuple(coords_str):
return tuple(coords_str.split(','))
output_list = [to_tuple(obSet['results'][i]['location']) for i in range(obSet['total_results'])]
You can of course replace to_tuple() with a lambda function, I just wanted to make the example clear. Moreover, you could use map() to have a tuple with floats instead of string: return tuple(map(float,coords_str.split(','))).
Let's try to give this a shot, starting with just 1 location:
>>> (long, lat) = obSet['results'][0]['location']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack
Alright, so that didn't work, but why? It's because the longitude and latitude coordinates are just 1 string, so you can't unpack it immediately as a tuple. We must first separate it into two different strings.
>>> (long, lat) = obSet['results'][0]['location'].split(",")
From here we will want to iterate through the whole set of results, which we know are indexed from 0 to n. tuple(obSet['results'][i]['location'].split(",")) will give us the tuple of longitude, latitude for the result at index i, so:
>>> [tuple(obSet['results'][i]['location'].split(",")) for i in range(n)]
ought to give us the set of tuples we want.
I have a dictionary:
vd = {'Klein': [1,1,1], 'Fox-Epstein': [1,-1,0], 'Ravella': [-1,0,0]}
I need a procedure that iterates over the dictionary checking which entry is most similar to one provided as an argument. I have two procedures the first is nested in the second.
def policy_compare(sen_a, sen_b, voting_dict):
a = 0
for i in range(len(voting_dict[sen_a])):
a += voting_dict[sen_a][i] * voting_dict[sen_b][i]
return a
This returns the dot product of two of the selected entries.
def most_similar(sen, voting_dict):
a = []
for i in voting_dict.keys():
score = policy_compare(sen,i, voting_dict)
a += score
return a
The second procedure is not complete for two reasons:
At the moment it is returning an error and I can't see where I am going wrong.
It just returns a list of the dot products (The one with the greatest dot product in the most similar), whereas I require the 'key' who's scalar product with the chosen sen is largest.
FULL error.
Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
most_similar('Klein', vd)
File "/Users/anthony/Desktop/matrix/megalol.py", line 15, in most_similar
a += score
TypeError: 'int' object is not iterable
a is a list, score is an int. You can't add the two together. A list is iterated over in order to get the contents in order to add them to another - thus the "weird" error. It can't iterate over the int (score) in order to add it to the the list (a).
try a.append(score) to add score on to the end of it.
Here are some modifications to approach the solution you want:
vd = {'Klein': [1,1,1], 'Fox-Epstein': [1,-1,0], 'Ravella': [-1,0,0]}
def policy_compare(sen_a, sen_b, voting_dict):
a = 0
for i in range(len(voting_dict[sen_a])):
a += voting_dict[sen_a][i] * voting_dict[sen_b][i]
return a
def most_similar(sen, voting_dict):
a = []
for this_sen in voting_dict.keys():
if this_sen == sen:
continue
score = policy_compare(sen, this_sen, voting_dict)
a.append((this_sen, score))
return max(a,key=lambda sen: sen[1])
print most_similar('Klein', vd)
As someone else has said, you want to append to your list a. I've added the senator's name along with the dot product in a tuple (for each item in a) because the dictionary keys come out in arbitrary order and you won't know which one is being referred to by each entry in a otherwise. I've returned the maximum dot product entry from most_similar. Also, to avoid comparing senators with themselves you want to use continue (go back to the start of the loop for the next iteration), not pass (do nothing and continue with the current iteration).
I am writing a function to remove duplication in one list. For specific:
input : a list
output: a list without any duplication
this is my code:
def remove_duplicate(s_list):
for member in s_list:
for other in s_list.remove(member):
if other == member:
s_list.remove(other)
return s_list
After that, I try to run remove_duplicate([1,2,3,4]) and the error is
for other in s_list.remove(member):
TypeError: 'NoneType' object is not iterable
I would suggest to work with two lists instead of changing one list in-place, if possible.
If order is not important, you can use a set:
dup_list = [1,1,2,3,2,5,2]
dupfree_list = list(set(dup_list))
Otherwise, if the order of elements is important, you can note which elements you have already seen:
dupfree_list = []
for e in dup_list:
if e not in dupfree_list:
dupfree_list.append(e)
I think the most Pythonic way is to use a set which removes duplicates:
listwithduplicates = [1,2,3,3]
listwithduplicates = set(listwithduplicates)
The result is:
{2,1,3}
Note that sets are not ordered the way lists are.