The following code is a bit from a bigger piece. lines is a 2D list and keyss is a 1D list. All element in lines is the same length as keyss.
datadict = []
for element in lines:
for index in range(len(element)):
datadict.append({keyss[index]: element[index]})
I was wondering if there was a way of writing this using dictionary comprehension? This is more of a curious question as the shown code works just fine for what I'm doing. I've been trying and couldn't find a way too. If you can could go over the syntax of how it would look a bit as well, Thanks!
EDIT#1:
Reading through the responses, I realized it wasn't really working. I'm trying to do a list comprehension where every element is a dictionary comprehension. I'm not entirely sure if that is possible or not. I want to make a list of dictionaries where I take every element in keyss and match index for index in a element in lines which is a list, if that makes sense.
EDIT #2:
I found data_list = [{keyss[i]:row[i] for i in range(len(keyss))} for row in lines] to work.
A dictionary comprehension creates a dictionary. You want a list comprehension:
datalist = [{keyss[index]:element[index]}) for element in lines
for index in range(len(element))]
You can find the documentation on the syntax here.
Your current code doesn't create a dictionary, but if that was your intent, this can be accomplished by
dict(zip(keyss, elements))
or the dictionary comprehension
{key: value for key, value in zip(keyss, elements)}
As mentioned by eugene, it will be list comprehension and not dict comprehension. You may further simplify the code by using zip() as you need the from element and keyss list corresponding to same index. Hence, your simplified list comprehension expression should be as:
datalist = [{k: e} for elements in lines for e, k in zip(elements, keyss)]
Related
I have a list of lists in my script:
list = [[1,2]
[4,3]
[6,2]
[1,6]
[9,2]
[6,5]]
I am looking for a solution to sum up the contents of each "sublist" within the list of lists. The desired output would be:
new_list = [3,7,8,7,11,11]
I know about combining ALL of these lists into one which would be:
new_list = [27,20]
But that's not what i'm looking to accomplish.
I need to combine the two values within these "sublists" and have them remain as their own entry in the main list.
I would also greatly appreciate it if it was also explained how you solved the problem rather than just handing me the solution. I'm trying to learn python so even a minor explanation would be greatly appreciated.
Using Python 3.7.4
Thanks, Riftie.
The "manual" solution will be using a for loop.
new_list = []
for sub_list in list:
new_list.append(sum(sub_list))
or as list compherension:
new_list = [sum(sub_list) for sub_list in list]
The for loop iterates through the elements of list. In your case, list is a list of lists. So every element is a list byitself. That means that while iterating, sub_list is a simple list. To get a sum of list I used sum() build-in function. You can of course iterate manually and sum every element:
new_list = []
for sub_list in list:
sum_val = 0
for element in sub_list:
sum_val = sum_val + element
new_list.append(sum_val)
but no need for that.
A better approach will be to use numpy, which allows you to sum by axis, as it looks on list of lists like an array. Since you are learning basic python, it's too soon to learn about numpy. Just keep in mind that there is a package for handling multi-dimensions arrays and it allows it perform some actions like sum on an axis by your choice.
Edit: I've seen the other solution suggest. As both will work, I believe this solution is more "accessible" for someone who learn to program for first time. Using list comprehension is great and correct, but may be a bit confusing while first learning. Also as suggested, calling your variables list is a bad idea because it's keyword. Better names will be "my_list", "tmp_list" or something else.
Use list comprehension. Also avoid using keywords as variable names, in your case you overrode the builtin list.
# a, b -> sequence unpacking
summed = [a + b for a, b in lst] # where lst is your list of lists
# if the inner lists contain variable number of elements, a more
# concise solution would be
summed2 = [sum(seq) for seq in lst]
Read more about the powerful list comprehension here.
I am having a hard time interpreting nested iteration inside a list comprehension. Below code
movie = []
genre = []
for movie_ids in ratings["movie_id"].values:
movie.append(movie_ids)
genre.append([x for movie_id in movie_ids for x in genres_dict[movie_id]])
If I print genre[0] suppose I see a result [a,b,c]
My understanding from this and many others on the internet was that I can replace the line
genre.append([x for movie_id in movie_ids for x in genres_dict[movie_id]])
With
for movie_id in movie_ids:
if movie_id in genres_dict:
genre.append(genres_dict[movie_id])
But that gives a different result when I print genre[0]
What am I missing?
Please suggest
With the list comprehension, you are also iterating over the contents of genres_dict[movie_id]. This code would not quite translate into the for loop you provided, but instead into
for movie_id in movie_ids:
for x in genres_dict[movie_id]
genre.append(x)
I have omitted the if statement because, although it is not a bad idea to test whether the key exists, the nested iteration does not perform this test either. Nested iteration essentially performs the for loops you provide, nested, from the left to the right, and then appends the result of the expression.
Furthermore, appending the result of a list comprehension does not add every element of the list comprehension individually, but instead the entire list as one element. So the code actually performs
list_out = []
for movie_id in movie_ids:
for x in genres_dict[movie_id]
list_out.append(x)
genre.append(list_out)
If you want to add all of the elements of the list comprehension, you should instead use list.extend, which takes an iterable as an argument and adds every element to the list. In your original code this would be
genre.extend([x for movie_id in movie_ids for x in genres_dict[movie_id]]).
The list comprehension is actually flattening the array for you as it iterates over the inner content also.
The equivalent code block would be this. Notice the extend vs append.
for movie_id in movie_ids:
if movie_id in genres_dict:
genre.extend(genres_dict[movie_id])
The extend takes care of iterating over each item and adding it to the genre list. See docs for append vs extend.
https://docs.python.org/3/tutorial/datastructures.html
I am reading items from a txt file into a list and then converting it into a dictionary as follows-
def getfeatures_into_list(inputfilename):
fid=open(inputfilename,"r")
dict_Lab_Features=defaultdict(int)
list1=[]
for line in fid:
list1.append(line.rstrip().lower())
list1=list(set(list1)) #Removing duplicates
c=0
for items in sorted(list1):
dict_Lab_Features[items]=c
c+=1
dict_Lab_Features=sorted(dict_Lab_Features.items(), key=operator.itemgetter(1))
print(dict_Lab_Features['Hello'])
I am getting error in the print statement
list indices must be integer,not str
Edit I want to sort the dict by value in ascending order.
In this line:
dict_Lab_Features=sorted(dict_Lab_Features.items(), key=operator.itemgetter(1))
you have reassigned dict_Lab_Features so that it is a list. This is because the output of sorted() is always a list. Naturally, a list cannot take a string as an index.
You should learn to think of dictionaries as inherently unsorted. There is such a thing as an OrderedDict for when you really need to keep track of insertion order, but for most purposes, a regular dict is fine. You just have to get into the habit of traversing the dictionary in the desired order, not worrying about whether the dictionary is stored in any kind of order.
The usual way to traverse a dictionary in sorted order is to just loop over the sorted keys, such as:
for key in sorted(dict_Lab_Features):
print dict_Lab_Features[key]
or
for key, value in sorted(dict_Lab_Features.items()):
print value
Or, if you want to loop over the sorted values,
for value in sorted(dict_Lab_Features.values()):
print value
You cannot sort a dict. Dicts are unordered mappings of elements.
Let's analyize the following line:
dict_Lab_Features=sorted(dict_Lab_Features.items(), key=operator.itemgetter(1))
From the documentation of sorted:
Return a new sorted list from the items in iterable.
So after that, dict_Lab_Features is a sorted list of key-value tuples. After that you try to index it with 'Hello'
print(dict_Lab_Features['Hello'])
Here you try to index that list with 'Hello', that's why you get the error list indices must be integer,not str
dict_Lab_Features stops being a dict when you call dict.items(). A dict.items() object cannot be addressed using string keys (it's really just a list of tuples [(key, value), ... ]).
Furthermore, "sorting" a dictionary you then intend to use by name doesn't make much sense either. Looks like you either need a collections.OrderedDict or you should skip ordering altogether
Up until now I have been using this code to uniquify (remove duplicates) from list in python:
my_list = list(set(my_list))
I now have a list of lists, I want to be able to remove duplicates from within the list of lists. For example:
(['possible-duplicate', 'random-data'], ['possible-duplicate', 'random-data'], ['possible-duplicate', 'random-data'])
I want to remove the whole sublist if possible-duplicate is a duplicate.
Can this be done?
Thanks
seen = set()
[sublist for sublist in my_list if sublist[0] not in seen and not seen.add(sublist[0])]
This happens to preserve order as well, which list(set(...)) does not.
Make a dictionary from your data:
data = (['possible-duplicate', '12345'],
['not-a-duplicate', '54321'],
['possible-duplicate', '51423'])
data_unique = dict(data)
Result is {'not-a-duplicate': '54321', 'possible-duplicate': '51423'}, or if you prefer a list of tuples, use date_unique.items(), which gives you [('not-a-duplicate', '54321'), ('possible-duplicate', '51423')].
Or for the more general case, where the sublists have more than two elements, you can use this
data_unique = dict((d[0], d) for d in data)
and then use data_unique.values() to reclaim the "uniquified" list.
I've looked around into list comprehensions on here, and can find a solution for this.
Closest I've come is questions that advice using enumerate() while iterating in a list comprehension.
What I'd like to do is access the prior element in a list comprehension. The context is this question on another StackExchange site.
Basically, if I get this string from stdin - 4,6,+2,+8, I'd like to output the array that is the integer of the number, or the number plus the value of the prior element. In the given case the final array is: 4,6,8,16 - or 4,6,6+2,(6+2)+8. Going from left to right with an array and for loop its trivial to generate, but I'm curious to know if it can be done in a single list comprehension.
As for what I have:
from sys import*
s=argv[1].split(',')
for i in range(len(s)):
s[i]=eval(`s[i-1]`*(s[i][0]=='+')+s[i])
print s
Which prints the correct result, however the following list comprehension does not:
s=argv[1].split(',')
s=[eval(s[i-1]*(x[0]=='+')+x) for i,x in enumerate(s)]
print s
Which results in:
[4, 6, 8, 10]
Which is equivilient to 4, 6, +2+6, +2+8.
What I'd like to be able to do finally is something along the lines of:
s=[eval(PRIOR_VALUE*(x[0]=='+')+x) for x in argv[1].split(',')]
So can I easily access the prior computed element of a list comprehension in the same list comprehension?
So can I easily access the prior computed element of a list comprehension in the same list comprehension?
Easily? No.
If you want to make things difficult for yourself, there are plenty of ways to save state information in a list comprehension. For example,
prev = [None]
s = [prev.__setitem__(0, val) or val
for item in list
for val in [something(item, prev[0])]]
This is not a good idea.