When I was a python beginner, I could create a multiple lines for loop that make a list of 1~100:
a=[]
for i in range(1,101):
a.append(i)
When I knew how to write a single line for loop, I could simply my code.
a=[ _ for _ in range(1,101)]
When I review python document and relearn python in detail now, I find range() built-in function it can directly make a list, but I look no one doing this. Why?
a=range(1,101)
In Python 2.x
If you want to create a list of numbers from 1 to 100, you simply do:
range(1, 101)
In Python 3.x
range() no longer returns a list, but instead returns a generator. We can easily convert that into a list though.
list(range(1, 101))
When I review python document and relearn python in detail now, I find
range() built-in function it can directly make a list, but I look no
one doing this.
Depends, if you are using Python 2.X it does but for Python 3.X it produces a range object which should be iterated upon to create a list if you need to.
But in any case for all practical purpose extending a range object as a List comprehension is useless and have an unnecessary memory hogging.
Related
I am trying to implement a genetic algorithm in python. I have a list of 100 objects, sorted, and I need to access the top 30 plus 20 random others. My method is:
random.shuffle(list[30:]) #keep top 30, shuffle the rest
for x in range (50):
list[x].do_stuff
This doesn't work, the list is unchanged. Is my syntax wrong or is my entire method impossible?
thanks
you probably want to do this
your_sliced_list = a[30:]
random.shuffle(your_sliced_list)
a[30:] = your_sliced_list
list is a python builtin so you shouldn't use it as a variable name as it overwrites the builtin, thats why in the code I have used a instead of list.
The reason why your code wasn't working was that when you slice the list it creates a new list which isn't assigned to a variable and random.shuffle shuffles that.
I am learning lists and trying to create a list and add data to it.
mylist=[]
mylist[0]="hello"
This generates Error.
Why cant we add members to lists like this, like we do with arrays in javascript.
Since these are also dynamic and we can add as many members and of any data type to it.
In javascript this works:
var ar=[];
ar[0]=333;
Why this dosent work in Python and we only use append() to add to list.
mylist[0] = 'hello' is syntactic sugar for mylist.__setitem__(0, 'hello').
As per the docs for object.__setitem__(self, key, value):
The same exceptions should be raised for improper key values as for
the __getitem__() method.
The docs for __getitem__ states specifically what leads to IndexError:
if value outside the set of indexes for the sequence (after any
special interpretation of negative values), IndexError should be
raised.
As to the purpose behind this design decision, one can write several chapters to explain why list has been designed in this way. You should familiarise yourself with Python list indexing and slicing before making judgements on its utility.
Lists in Python are fundamentally different to arrays in languages like C. You do not create a list of a fixed size and assign elements to indexes in it. Instead you either create an empty list and append elements to it, or use a list-comprehension to generate a list from a type of expression.
In your case, you want to add to the end, so you must use the .append method:
mylist.append('hello')
#["hello"]
And an example of a list comprehension:
squares = [x**2 for x in range(10)]
#[1,4,9,16,25,36,49,64,81,100]
I thought that the range() function returns a list with the arguments that you have put inside the parentheses. But when I type range(4) in IDLE, I get range(0, 4) as output. Similarly, when I type print(range(4)), I also get range(0, 4) as output. I am currently using python 3.5.
I am currently studying python with the following eBook: "How To Think Like a Computer Scientist" and in that eBook, they provide active code blocks where you can run python code. And when I run print(range(4)) in there, I do get the list that I expected, i.e. [0, 1, 2, 3].
Can someone explain this to me?
Thanks in advance!
The book you are reading probably uses Python 2, where range returns a list.
In Python 3, range returns an immutable sequence type instead.
Your book was probably written using Python 2.x. In Python 2.x the range function actually returned a list that the for loop would iterate through. In Python 3.x, the range function is it's own type, and is actually a generator function so the numbers are produced on the fly as the for loop is executing.
You can still create a list from a range function if you pass it into a list like so.
list(range(4))
Which would output a list with the following contents.
[0,1,2,3]
print(range(10)) returns range(0, 10) as output
In many ways the object returned by range() behaves as if it is a list, but in fact it isn’t. It is an object which returns the successive items of the desired sequence when you iterate over it, but it doesn’t really make the list, thus saving space.
We say such an object is iterable, that is, suitable as a target for functions and constructs that expect something from which they can obtain successive items until the supply is exhausted. We have seen that the for statement is such an iterator. The function list() is another; it creates lists from iterables:
list(range(5)) returns [0, 1, 2, 3, 4] as output
range(a, b) return an instance of class range. You can check it by print(type(range(1, 5))).
And what you expect can be got by print(list(range(a, b))).
according to this:
So in Python 3.x, the range() function got its own type. In basic terms, if you want to use range() in a for loop, then you're good to go. However you can't use it purely as a list object. For example you cannot slice a range type.
however if you call print() on it, the print function will try to create a string representation of the range-object, and this string-representation is equivalent to the string representation of a list.
If you want the list you can do list(range(<parameters>))
At the moment, I have a piece of code with lots of lists equal to the function of another list, embedded in a loop in Python:
Power = [x,y,z]
Force = []
for i in range(len(Power)):
Force.append(((function(Power[i])-0.5))/slope)
I would like to simplify it down to:
Force = function(Power[i])-0.5))/slope)
but it doesn't work. It does however work when there's no function, just a simple relationship. Is this possible in Python?
You can use a list comprehension:
Force = [(function(x)-0.5)/slope for x in Power]
As far as I am aware the most concise / simplest way to do this is via list comprehension, in particular you can do something as follows:
Force = [(function(Power[i])-0.5)/slope for i in range(len(Power))]
Very similar to what you have already done earlier, but comes in a nice and simple one line expression.
I am trying to find a way of creating objects based on the size of two lists. I have to create an object for each combination of indices of the two lists, i.e. if both lists is of the length 3, 9 new objects should be created and defined.
The lists can be of rather large lengths and it would make the script a lot nicer if I did not have to use an if loop to go through all possible combinations.
A first I thought I could do the following:
for i in range(len(list1)):
for j in range(len(list2):
Name_of_Object+[i]+[j] = (object definition)
But this is not possible and I get the following error:
SyntaxError: can't assign to operator
But is there a way of creating objects based on indices of a list?
Best,
Martin
(I am using the Canopy environment to do my python programming.)
Why not define these objects in a list and then you can access individual variables as li[i][j]
li = []
for i in range(len(list1)):
tempLi = []
for j in range(len(list2)):
tempLi.append((object definition))
li.append(tempLi)
we can't concatenate to an operator but we can use it an array. that is
Name_of_Object[i][j] = (object definition)
Maybe you could do your assignment with an exec statement
exec("Name_of_Object{0}{1} = object declaration".format(i,j))
But I don't think this is a good idea because you won't be able to call your objects without an exec statement further in your program unless you specificaly want Name_of_Object01 or Name_of_Object02,...
for instance if you need to loop over your instances each time you want to do something with it you will need to write:
exec("Name_of_Object{0}{1}.method(...)".format(i,j))
So I think you should you use a multidimensional array