Understanding python nested iteration inside a list comprehension - python

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

Related

How do i write this in list comprehension in python

I want to write a list comprehension that will have print an element out of an array every other element. How do I do so?
for item in results:
record = extract_record(item)
if record:
records.append(record)
in Python 3.8 or later you could make use of the assignment expression and do something like
records = [record for item in results if (record := extract_record(item))]
This avoids having to extract the record twice.
The list comprehension equivalent of the above will be:
records = [extract_record(item) for item in results if extract_record(item)]
Note that extract_record() is needed twice and hence not so useful.

How do I append items to a list inside a for loop in python?

What I want to do is take names from namelist, compare those to names in banklist, and if there is an item in banklist which looks a lot like an item in namelist, I want to append that item to a closematchlist. The goal of this is to find items that occur in both lists, even if there is a spelling error in namelist.
When I print(closematch), it works like intended: the close matches in banklist get found and printed. However, when I try to append those items to a list, the result of print(closematchlist) is [].
for name in namelist:
closematch = difflib.get_close_matches(name, banklist, 1, 0.8)
closematchlist = list()
closematchlist.append(closematch)
print(closematch)
print(closematchlist)```
difflib.get_close_matches() is a list of close matches. You don't need to copy it to a new list.

Inquiry on dictionary comprehension

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)]

Get unique entries in list of lists by an item

This seems like a fairly straightforward problem but I can't seem to find an efficient way to do it. I have a list of lists like this:
list = [['abc','def','123'],['abc','xyz','123'],['ghi','jqk','456']]
I want to get a list of unique entries by the third item in each child list (the 'id'), i.e. the end result should be
unique_entries = [['abc','def','123'],['ghi','jqk','456']]
What is the most efficient way to do this? I know I can use set to get the unique ids, and then loop through the whole list again. However, there are more than 2 million entries in my list and this is taking too long. Appreciate any pointers you can offer! Thanks.
How about this: Create a set that keeps track of ids already seen, and only append sublists where id's where not seen.
l = [['abc','def','123'],['abc','xyz','123'],['ghi','jqk','456']]
seen = set()
new_list = []
for sl in l:
if sl[2] not in seen:
new_list.append(sl)
seen.add(sl[2])
print new_list
Result:
[['abc', 'def', '123'], ['ghi', 'jqk', '456']]
One approach would be to create an inner loop. within the first loop you iterate over the outer list starting from 1, previously you will need to create an arraylist which will add the first element, inside the inner loop starting from index 0 you will check only if the third element is located as part of the third element within the arraylist current holding elements, if it is not found then on another arraylist whose scope is outside outher loop you will add this element, else you will use "continue" keyword. Finally you will print out the last arraylist created.

Add a list of lists to a list of lists with a list comprehension

I've got list of lists, (specifically the results of a results of a SQL query) that I want to add to the end of another list of lists (the results from a previous query/queries). The list comprehension that I think should do this
[results.append(result) for result in currentResults]
doesn't append the rows, but instead adds None where each row should be. However, if I do this with an if statement
for result in currentResults:
results.append(result)
it works perfectly.
Why do these two statements not do the same thing, and is there a way to do this with a list comprehension?
The return value of .append() is None. That return value is what is going into your comprehension.
If the for loop works perfectly, then you should be able to just replace it with
results += list(currentResults)
Or, perhaps you might prefer:
results.extend(currentResults)
A list comprehension would work like:
results += [r for r in currentResults]

Categories

Resources