Convert pythonic loop into traditional loop style - python

I am a beginner in Python and kindly I have a question: Given the following:
np.asarray([self.simulate(c) for c in challenges])
I want to break it down to look familiar in the traditional coding way. Can I say it is equivalent to:
for c in challenges:
y = self.simulate(c)
y = np.asarray[y]
Thank you.

It's not called "pythonic looping", but list comprehension.
The equivalent would be:
items = []
for c in challenges:
items.append(self.simulate(c))
nparr = np.asarray(items)

The problem with your method is that you're are not building a list, such as this list comprehension does. Rather, you are simply indexing one item from np.asarray, and never saving the value. Furthermore, you don't even want to be indexing np.asarray, you want to pass a list to its constructor.
You need to create a temporary list to hold the return value of self.simulate(c) on each iteration of challenges and pass that list to np.asarray:
temp = []
for c in challenges:
temp.append(self.simulate(c))
array = np.asarray(temp)
Also, just to let you know, the "pythonic loop" you're referring to is usually called a list comprehension. "Pythonic" is just a name us Python community members use to describe something that is idiomatic to the Python language and its ideals.

Related

Using range function in Python

I am new to learning Python and have a question about using the range function to iterate a string.
Let's say I need to capitalize everything in the following string:
string = 'a b c d e f g'
Can I just write the following code?
for i in string:
i = i.upper()
return string
Or should I use the range function to iterate every element in the string?
Finally, a more general question is whenever I need to iterate all elements in a string/list, when should I use the range function and when can I just use the "for" loop?
Strings are a bad example, because strings in Python cannot be changed. You have to build a new one:
new = ''
for i in string:
new += i.upper()
For the sake of example, we're all going to ignore the fact that new = string.upper() would do this in one statement.
In general, when you iterate through an object, you are handed references to the members. You can't change the container object, but if the inner object is mutable, you can change it. Consider this silly example:
a = [[1],[2],[3],[4]]
for element in a:
element[0] *= 2
This will result in a being [[2],[4],[6],[8]], because we are allowed to modify those inner lists. We can't change the outer list.
AS A GENERAL RULE, if you find yourself writing for i in range(len(xxx)):, then there is a better way to do it. It isn't ALWAYS true, but it's a key Python learning point.

Is there a way to create a list comprehension from this?

I just learned how to create list comprehensions and I was looking back through my past projects to see where I can create comprehensions. I was successful with several, but then I got to this part of the code and I was wondering if there was any way to create a list comprehension from this:
scores = util.Counter()
for l in self.legalLabels:
scores[l] = self.weights[l] * trainingData[i]
Maybe I'm just thinking a bit too hard for this but I was wondering if there was any way to create a comprehension using this?
I was thinking something like:
[(scores(l) = self.weights[l] * trainingData[I]) for l in self.legalLabels]
but this does not work in terms of attributing each value to scores[l].
Any help would be greatly appreciated!
If util.Counter() is a dictionary like collections.Counter, you can update it with a dictionary via its update method. So you can use:
scores = util.Counter()
scores.update({L: self.weights[L] * trainingData[i] for L in self.legalLabels})
Then for some label x, you can access the result via scores[x].
List comprehension are for lists, dictionary comprehensions for dictionaries. The latter are mentioned in the docs.
EDIT: I didn't pay attention to scores = utils.Counter(), so I provided an answer which is list comprehension. See #jpp's answer for correct approach.
Your approach is right, but there is no assignment within comprehension. You must make one outside of it
scores = [self.weights[l] * trainingData[I]) for l in self.legalLabels]

How to have best use of Python lists?

My question is te following:
I'm new to Python programming and I'm a little confused about the correct use of lists.
When I want for example to create a list of 10 elements I am doing something like:
list = [None for x in range(10)]
And when I have something to put on it, I do:
list[lastPosition] = data
But after some research I noticed that this use for lists is not efficient or recommended. But how other way could a list be inicialized before I have all the data? My idea is to have a list (specially something like Java's Collections) inicialized and as the data comes I fill it.
I hope my question is clear enough.
If you don't know in advance how many elements will be in the list,
then don't try to allocate 10 elements. Start with an empty list and use the append function to append to it:
lst = []
...
lst.append(value)
If for some reason you really need to initialize a list to a constant size,
and the initial elements are immutable values,
then you can do that like this:
lst = [None] * 10
If the initial elements are mutable values,
you most probably don't want to use this technique,
because all the elements will all point to the same instance.
In that case your original technique is mostly fine as it was:
lst = [SomeClass() for _ in range(10)]
Note that I renamed the variable from list to lst,
because list is a built-in class in Python,
and it's better to avoid such overlaps.

Build Dictionary in Python Loop - List and Dictionary Comprehensions

I'm playing with some loops in python. I am quite familiar with using the "for" loop:
for x in y:
do something
You can also create a simple list using a loop:
i = []
for x in y:
i.append(x)
and then I recently discovered a nice efficient type of loop, here on Stack, to build a list (is there a name for this type of loop? I'd really like to know so I can search on it a little better):
[x.name for x in y]
Ok, that being said, I wanted to go further with the last type of loop and I tried to build a python dictionary using the same type of logic:
{x[row.SITE_NAME] = row.LOOKUP_TABLE for row in cursor}
instead of using:
x = {}
for row in cursor:
x[row.SITE_NAME] = row.LOOKUP_TABLE
I get an error message on the equal sign telling me it's an invalid syntax. I believe in this case, it's basically telling me that equal sign is a conditional clause (==), not a declaration of a variable.
My second question is, can I build a python dictionary using this type of loop or am I way off base? If so, how would I structure it?
The short form is as follows (called dict comprehension, as analogy to the list comprehension, set comprehension etc.):
x = { row.SITE_NAME : row.LOOKUP_TABLE for row in cursor }
so in general given some _container with some kind of elements and a function _value which for a given element returns the value that you want to add to this key in the dictionary:
{ _key : _value(_key) for _key in _container }
What you're using is called a list comprehension. They're pretty awesome ;)
They have a cousin called a generator expression that works like a list comprehension but instead of building the list all at once, they generate one item at a time. Hence the name generator. You can even build functions that are generators - there are plenty of questions and sites to cover that info, though.
You can do one of two things:
x = dict(((row.SITE_NAME, row.LOOKUP_TABLE) for row in cursor))
Or, if you have a sufficiently new version of Python, there is something called a dictionary comprehension - which works like a list comprehension, but produces a dictionary instead.
x = {row.SITE_NAME : row.LOOKUP_TABLE for row in cursor}
You can do it like this:
x = dict((row.SITE_NAME, row.LOOKUP_TABLE) for row in cursor)

Pythonic way of saying "if all of the elements in list 1 also exist in list 2"

I want to return true from the if statement only if all of the elements from list 1 also exist in list 2 (list 2 is a superset of list 1). What is the most pythonic way of writing this?
You can use set operations:
if set(list1) <= set(list2):
#...
Note that the comparison itself is fast, but converting the lists to sets might not (depends on the size of the lists).
Converting to a set also removes any duplicate. So if you have duplicate elements and want to ensure that they are also duplicates in the other list, using sets will not work.
You can use built-in all() function:
if all(x in sLVals for x in fLVals):
# do something
In case of using sets think you can take a look at difference method as far as i know it is quite faster way:
if set(fLVals).difference(sLVals):
# there is a difference
else:
# no difference
Either set.issuperset or all(x in L2 for x in L1).
This one came straight out of good folks at MIT:
from operator import and_
reduce(and_, [x in b for x in a])
I tried to find the "readings.pdf" they had posted for the 6.01 class about a year ago...but I can't find it anymore.
Head to my profile and send me an email, and I'll send you the .pdf where I got this example. It's a very good book, but it doesn't seem to be a part of the class anymore.

Categories