writing for loop into list comprehension - python

I have written a for loop but want to implement it as list comprehension. Followed the usual guides for translating it to a list comprehension, but for some reason the for loop is working but the list comprehension isn't
Below is both my for loop as well as the list comprehension code. Note that "tipos" is a series and "airbnb" a dataframe (though that should not be relevant, I think.
for i in range(len(tipos)):
porcentajes.append(tipos[i]/airbnb.room_type.count()*100)
porcentajes
porcentajes=[porcentajes.append(tipos[i]/airbnb.room_type.count()*100) for i in range(len(tipos))]
porcentajes
Using the for loop I get the list I want, but using the list comprehension I get a list full of Nones. I'd be expecting to get the same result as with the for loop. How do I correct the list comprehension?

I think what you want is actually:
porcentajes=[(tipos[i]/airbnb.room_type.count()*100) for i in range(len(tipos))]
(no need to append... you're creating the list by doing the comprehension)
However, I'm not sure why you need the index either, you can likely just loop over the items:
porcentajes=[(t/airbnb.room_type.count()*100) for t in tipos]

Related

How do loops work in list assignments in python?

Consider the following command:
elite_states = [s for i in range(len(states_batch))
if rewards_batch[i]>=reward_threshold for s in states_batch[i]]
I found that is equivalent to the following loop:
_l=[]
for i in range(len(states_batch)):
for s in states_batch[i]:
if rewards_batch[i]>=reward_threshold:
_l.append(s)
However I don't get how the loop after s in the first command becomes the outer loop in its equivalent. I want to understand the format of the command so I get how it works!
I found that is equivalent to the following loop:
It isn't. List comprehensions are read in the same way as ordinary nested loops. First you loop over range(len(states_batch)), then, inside this loop, you check if rewards_batch[i]>=reward_threshold, next, inside this condition, the last loop is ran.
So the "expanded" version looks like this:
_l=[]
for i in range(len(states_batch)):
if rewards_batch[i]>=reward_threshold: # `if` and the inner `for` are switched
for s in states_batch[i]:
_l.append(s)
In code, this is extremely similar to the comprehension:
_l = [
s
for i in range(len(states_batch))
if rewards_batch[i]>=reward_threshold
for s in states_batch[i]
]
The only difference is that loops in comprehensions are written sequentially (one after the other), but in the expanded version they become nested one inside the other, the last loop in the comprehension being nested the deepest.

List append in a "for" loop

I am trying to get a list of elements using a for loop to index my previous list. Here's the code:
for index in range(1,810):
list.extend(t[index])
list.extend(t[index+1])
list.extend(t[index])
I already have a list named "list" and t is an other list.
To be more specific I want to make my list like this.
t1,t2,t1,t2,t3,t2,t3,t4 etc.
I get this error TypeError: 'float' object is not iterable.
You should be using list.append since list.extend works on iterables; i.e. you can do stuff like lst=[1,2,3];lst.extend([4,5]) which would give you [1,2,3,4,5]
see this link if you want to read more
The other answers suggesting you use append fix your issue, but appending is very inefficient. You should use a list comprehension. Also, "list" is a keyword, so you should use another name.
my_list = [item for index in range(1,810) for item in [t[index],t[index+1],t[index]] ]

List comprehension in Python?

I have this list :
a = [1,2,3,4,5]
I want to delete each element from the list. This is how I'm doing.
for i in range(0,len(a)):
del a[0]
Can I use list comprehension in this? such as del a[0] for i in range(0,len(a))
List comprehensions are for creating lists, not destroying them. They are not the right tool for this job.
If you want to clear the contents of a list, the quickest way is
del a[:]
This is a slice deletion. The omitted beginning and ending points default to the start and end of the list.
Note that frequently, it's better to just replace the list with a new one:
a = []
This works even if a didn't already exist, and modifications to the new list won't interfere with any other parts of the code that needed the old list. These attributes are often, though not always, desirable.
You wouldn't usually do this with a loop at all. To clear an existing list, use a[:] = [].
No, you cannot del components in a list comprehension. Why would you want to do that in the first place? A list comprehension is for creating a list, not for modifying.
You can replace the list with a different one created with a list comprehension.
The reason is that a list comprehension needs an expression. But del is a statement.
List comprehension (coming from functional programming, where nothing is ever mutated) is for building lists. Since it appears you want to clear out the elements of an existing list (and not creating a new list with only some of the elements etc.), list comprehension is not the right tool.
That said, list comprehension can be abused to do it:
[a.pop() for i in range(len(a))]
NOTE: This is a bad idea (since it uses list comprehenstion for something completely different than what it is intended for) and I would strongly recommend you do not use it.

How to use list comprehension on this for loop in python

I've just learned of list comprehension but I can't quite get it to work in the right context.
my for loop is:
results and instances are lists
for i in results:
instances.remove(i)
results.remove(i)
I tried [i for i in one if one.count(i)<2 if two.count(i)<2] but it doesn't work. I can get it to work on just one of them with this, [i for i in one if one.count(i)<2], but I wanted to incorporate both of them into the same loop. Can someone show me the easiest way to go about this?
Assuming results is a list. You seem to be trying to do this
for i in results:
instances.remove(i)
del results[:]
list comprehension is the wrong thing to use here. You're not trying to create a new list from a sequence.
This loops is similar, but will remove the instances in the reverse order
while results:
instances.remove(results.pop())
You need to first take the results out of the for loop. Set it after it and then delete it once the for loop has finished.

Improving Python Snippet Performance

This statement is running quite slowly, and I have run out of ideas to optimize it. Could someone help me out?
[dict(zip(small_list1, small_list2)) for small_list2 in really_huge_list_of_list]
The small_lists contain only about 6 elements.
A really_huge_list_of_list of size 209,510 took approximately 16.5 seconds to finish executing.
Thank you!
Edit:
really_huge_list_of_list is a generator. Apologies for any confusion.
The size is obtained from the result list.
Possible minor improvement:
[dict(itertools.izip(small_list1, small_list2)) for small_list2 in really_huge_list_of_list]
Also, you may consider to use generator instead of list comprehensions.
To expand on what the comments are trying to say, you should use a generator instead of that list comprehension. Your code currently looks like this:
[dict(zip(small_list1, small_list2)) for small_list2 in really_huge_list_of_list]
and you should change it to this instead:
def my_generator(input_list_of_lists):
small_list1 = ["wherever", "small_list1", "comes", "from"]
for small_list2 in input_list_of_lists:
yield dict(zip(small_list1, small_list2))
What you're doing right now is taking ALL the results of iterating over your really huge list, and building up a huge list of the results, before doing whatever you do with that list of results. Instead, you should turn that list comprehension into a generator so that you never have to build up a list of 200,000 results. It's building that result list that's taking up so much memory and time.
... Or better yet, just turn that list comprehension into a generator comprehension by changing its outer brackets into parentheses:
(dict(zip(small_list1, small_list2)) for small_list2 in really_huge_list_of_list)
That's really all you need to do. The syntax for list comprehensions and generator comprehensions is almost identical, on purpose: if you understand a list comprehension, you'll understand the corresponding generator comprehension. (In this case, I wrote out the generator in "long form" first so that you'd see what that comprehension expands to).
For more on generator comprehensions, see here, here and/or here.
Hope this helps you add another useful tool to your Python toolbox!

Categories