So i am attempting to create 3 different lists one of 1k, one of 10k, and one of 100k items long populated with random numbers from 1 to 10million but i cant seem to figure out why it keeps saying its invalid syntax. So far i have:
edit: okay it seems to have fixed the invalid syntax problem with some tweaking but still gives me:
Traceback (most recent call last):
File "C:/Python32/funtime.py", line 16, in <module>
print (list[1])
TypeError: 'type' object is not subscriptable
this is exactly what i have typed in:
import random
def createlist(a):
blist =[]
count=0
while count <= a:
blist.append(random.randint(1,10000000))
count= count+1
return blist;
list1= createlist(10000);
print (list[1])
Traceback (most recent call last):
File "C:/Python32/funtime.py", line 16, in <module>
print (list[1])
TypeError: 'type' object is not subscriptable
Objects of type type are indeed not subscriptable. list is the name of the builtin list class, which is an instance of type. It doesn't make any sense to subscript it, so that's clearly not what you intended to do.
You meant print (list1[1]). list1 is the name you bound to your list object created by createlist(10000).
The trick to finding these sort of bugs is to look at the error message Python gave you. It's telling you exactly the problem line, and exactly why it's a problem. All that was missing was the realisation that list is not the name of the object you wanted to subscript.
A much shorter version would be:
>>> import random
>>> def create_list(length):
... return [random.randint(1,1000000) for _ in range(length)]
This demonstrates a couple of things:
A much more compact way to loop x times (the for _ in range(length) idiom)
List comprehensions to create lists, instead of repeated calls to append.
The use of _ as a variable name when you need the variable, but not the actual data in it. This is a somewhat common convention that crops up most often in list comprehensions. It isn't a problem not to use it, but it crops up often enough that it pays to be aware of it.
Hat-tip to #mgilson for his comment on another answer that reminded me the _ convention.
The following works fine on my system.
import random
def createlist(a):
blist =[]
count= 0
while count <= a:
blist.append(random.randint(1,1000000))
count=count+1
return blist
list1= createlist(10000)
print list1[1]
http://ideone.com/SL2bL <-- try it here.
I'd probably do it like this
import random
def createlist(a):
return [random.randint(1,1000000) for i in xrange(a)]
list1= createlist(10000)
print list1[1]
Or probably just skip the function..
list1 = [random.randint(1,1000000) for i in xrange(a)]
print list1[1]
As some other answers have stated, you could easily use list comprehension for something like this (the so-called Pythonic way):
somelist = [random.randint(1, 1000000) for i in xrange(10000)]
List comprehension is fast in Python because it is executed by underlying C code. Moreover, using xrange is more memory-efficient.
Note: By convention, when the loop-control variable is not used in Python, it is named _:
somelist = [random.randint(1, 1000000) for _ in xrange(10000)]
use a list comprehension (its way betta and makes you look pro, haha)
[random.randint(1, 1000000) for i in range(10000)]
First, you don't put a paren by while unless you're evaluating complex expressions.
Next, you used a semicolon to return your blist. Not necessary.
Finally...why not use a for loop?
import random
def createlist(a):
blist =[]
for x in xrange(a):
blist.append(random.randint(1,1000000))
return blist
list1= createlist(10000)
print list1[0]
Related
The below program is for entering the values to a list and print the list again after removing the duplicate entries... Can someone please have a look and let me know what would be the error in the program?
print ("Enter the Numbers into List \n")
list = []
n = int(input(""))
while n <= 1000:
list.append(n)
n = int(input(""))
m = len(list)
for i in range (0,m-1):
for j in range (i+1,m):
if list[i] == list[j]:
list.remove(j)
else:
pass
print (list)
When I run the program it gives below error:
File "python", line 23, in <module>
ValueError: list.remove(x): x not in list
There are several problems with your code.
The first is your assumption that list.remove() takes an index as its argument. It doesn't remove an element by index, but by value (see the method's documentation). The second is that if you modify a list as you iterate over it you may well find that this messes up your indexing:
>>> for i in range(len(lst)):
... if i == 2:
... del lst[i]
... else:
... print(lst[i])
...
1
2
Traceback (most recent call last):
File "<stdin>", line 5, in <module>
IndexError: list index out of range
The third (minor) issue is that you are using the name of a built-in type (list) as a variable in your code, which will "shadow" the built-in type, making it inaccessible.
There are a number of problems in your solution:
The one you run into is that the remove method removes the first element that matches the argument, but you use the index of the element as argument which does not need to be one of the element. Instead if you want to remove an element by index you should use del mylist[index] instead.
Second you're trying to modify an list while iterating through it and that's not a good thing, you will probably not getting the result from that that you expect.
Also a aestetically questionable construct is calling your list list, that name is already used by the type list. By doing so you run into the problem that you can't use the builtin list anymore and that could be confusing.
The pythonic way to do this is to use the library functions and not reinventing the wheel (and of course not calling your list list):
import collections
mylist[:] = list(collections.OrderedDict.fromkeys(mylist).keys())
What it does is using OrderedDict which retains the order of the keys to put the element into and then create a list from that and then put it in the original list.
That solution however assumes that the items are hashable, which might not be the case. Otherwise the only solution is to iterate twice through the list as Cunningham's answer shows (which is therefore slower).
You are trying to remove j not what is in list[j], you also need to make a copy of the list and remove from that, when you remove elements you change the size of the list so apart from an index error you will try to remove elements that are not there:
m = len(lst)
out = lst[:]
for i in range(m - 1):
for j in range(i + 1, m-1):
if lst[i] == lst[j]:
out.remove(lst[j])
print(out)
To remove from the original list, you can use a set and reversed:
seen = set()
for ele in reversed(lst):
if ele in seen:
lst.remove(ele)
seen.add(ele)
print(lst)
Or use an OrderedDict:
from collections import OrderedDict
print(list(OrderedDict.fromkeys(lst).keys()))
A simple way using comprehension would be assuming your list name is l to avoid clashing with the type list:
l = [ l[i] for i in range(len(l)) if l[i] not in l[:i] ]
It avoids a name clash with the builtin type list, and modifying a list that you are iterating, and is still O(n2/2)
as you keep deleting the elements the length of list keeps decreasing and the index you are accessing might not be accessible
instead do something like
list(set(t))
and dont name your lists as the "list" keyword
I just started with Python. Had Haskell before. In Haskell, I worked most of the time with/on lists. In Python I want do so.
I have a list of:
l = [1,2,3,4]
How can I add the 4 elements in the list, so that I get 10 as result (1+2+3+4)
I need a recursive function and an iterative (not clean and stable as iterative , but nevertheless).
In Haskell I did this:
sum [] = 0
sumlist(x:xs) = x + sumlist xs
In Python I tried this:
def sumlist(l)
if l == 0: #or Nil, i do not know
result 0
else:
l [0] + sumlist(l)
but that does not work, maybe I am still to focused on Haskell's implementation style.
Would be great if I get some help.
Edit:
If you do not wish to use sum, you can make your own function1:
>>> def sumlist(seq, start=0):
... return sumlist(seq[1:], start + seq[0]) if seq else start
...
>>> lst = [1, 2, 3, 4]
>>> sumlist(lst)
10
>>> lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> sumlist(lst)
45
>>> sumlist(lst, 10) # You can specify a number to start at too
55
>>>
1Note: It is assumed that you will pass in a sequence of numbers.
Just use the sum built-in:
>>> l = [1, 2, 3, 4]
>>> sum(l)
10
>>>
From the docs:
sum(iterable[, start])
Sums start and the items of an iterable from left to right and returns the total. start defaults to 0. The iterable's items are
normally numbers, and the start value is not allowed to be a string.
I haven't used Haskell, but in Python objects are rich in that they know how to work with other objects. You can think of it like the "interface between objects" is well understood, and everyone is expected to behave nicely:
EAFP
Easier to ask for forgiveness than permission. This common Python
coding style assumes the existence of valid keys or attributes and
catches exceptions if the assumption proves false. This clean and fast
style is characterized by the presence of many try and except
statements. The technique contrasts with the LBYL style common to many
other languages such as C.
So the idea is if there a function in the standard library called sum, you can be sure it does at least two things:
Knows how to sum up things it can sum up.
If it doesn't know how to sum it up, it will raise an Exception.
Once you understand how this works, you can start passing anything to sum to see what it does:
>>> sum((1,2,3)) # a list
6
>>> sum([1,2,3]) # a tuple
6
>>> sum((1,)) # a tuple with one object
1
>>> sum([2]) # a list with one object
2
So as long as the item is iterable, sum can do its thing. Of course, when you pass it something it cannot work with, you get the appropriate exception:
>>> sum(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> sum('1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Note that a string is iterable in Python, which is why you get a different exception.
After you comment here:
Is there another way summing them up , or is it just this one ?
Its worth pointing out the zen of python which is kind of a guide on what makes code "pythonic", which states:
There should be one-- and preferably only one --obvious way to do it.
So the obvious way to sum things up would be with a function named sum.
Your code isn't actually too far off. empty lists are "falsy", so you can do something like:
def sumlist(lst):
if not lst:
return 0
else:
# Add the first element to the sum of the remaining elements.
return lst[0] + sumlist(lst[1:])
Of course, I'm assuming that you're doing this as part of a homework assignment where you're learning about recursion -- This would be horrible in any sort of production code where you should really just use sum (the builtin function).
If you are looking for a method other than the obvious sum you can use reduce:
>>> l = [1,2,3,4]
>>> import operator
>>> reduce(operator.add, l)
10
If you want another function, you could do:
def sum_l(l):
rtr=0
while l:
rtr+=l.pop()
return rtr
That function is destructive to the list. If you want to keep the list, call it with a copy of the list:
n=sum_l(l[:])
Yet another (that does not destroy the list) is to use a for loop on the iterable:
def sum_l(l):
rtr=0
for e in l:
rtr+=e
return rtr
Here are two ways you can compute the sum:
Just use the in-built sum function:
sum(l)
Using a for loop:
sum_val = 0
for i in range(0, len(l)):
sum_val += l[i]
Using recursion to compute a sum is just waste of computing resources. Do not use recursion until its absolutely necessary.
Why is the for loop not working?
l=[1,2,3,4,5]
def times(x):
for i in len(x):
x[i]+=10
times(l)
print l
Ideally it should print the elements of the list incremented by 10. But it is giving me the following error:
Traceback (most recent call last):
File "ex1.py", line 5, in <module>
times(l)
File "ex1.py", line 3, in times
for i in len(x):
TypeError: 'int' object is not iterable
Where am I going wrong?
len function will return just the length of the list. Its just a number, so you cannot iterate it with the for loop.
Perhaps you wanted to use the xrange function, along with the len(x)
for i in xrange(len(x)):
We use xrange function here, because range function will create the entire list in memory before iterating. For example,
print range(10)
will give you the newly constructed list with elements from 0 to 9. Think about iterating a very big list. Lets say that the list's size is 10000000. It is really a waste of memory to generate numbers from 0 to 10000000, just for the sake of iterating, right? Thats why we use xrange.
xrange returns an iterable object which gives one number at a time while iterating. Its very memory efficient, as we don't have to construct the entire list.
Suggestion: Unless it is absolutely necessary to modify the original list, you can create a new list and return it.
def times(my_list, my_num = 10):
return [current_num + my_num for current_num in my_list]
l = [1,2,3,4,5]
l = times(l)
print l
It will have the same effect on the data, as the first one. But we use list comprehension to create a new list and we assign it to the variable l. So, now l points to the newly generated list instead of the old list.
This is because len(x) is just an integer, you need to create a list, e.g.
l=[1,2,3,4,5]
def times(x):
for i in range(len(x)):
x[i]+=10
times(l)
print l
For my homework assignment I am supposed to randomly select items in a list. so far I have this code,
import random
room = range(0, 365)
r = random.choice(room)
mySet = set(r)
However, when I attempt to run the program, it says that " 'int' is no iterable".
I was wondering how I can fix this problem?
set() requires an iterable (a list or tuple are iterables) as its argument, where you’ve supplied an integer.
If you want to choose random items (with fixed size) from a set:
list = random.sample(your_set, size);
or if you want to choose random items with random size:
size = random.randint(0, your_set_size):
list = random.sample(your_set, size):
Your set also just has a single value in it so you only have one thing to iterate over. random.choice returns only a single element in the sequence in this case an int. This isn't the cause of the python error (int is not iterable as sneeu says) but will lead to a different result than what you are looking for. random.sample is probably a better choice
However, when I attempt to run the program, it says that " 'int' is no iterable".
I was wondering how I can fix this problem?
Use randint:
>>> from random import randint
>>> randint(0, 360)
86
>>> var = randint(0, 360)
>>> isinstance(var, int)
True
set is actually a type in python, an object like list or dict. Thus, when you pass in an int from random.choice, it gives you an error, because it needs a list, something that you can loop through is an iterable object. So, for example:
>>> set([1,3,4,5,2])
set([1, 2, 3, 4, 5])
Will work, but what you tried to do is this:
>>> set(1) # 1 is used as a number here
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: 'int' object is not iterable
If you wish to create a random list, you can do something like this:
>>> [randint(0, 360) for _ in xrange(10)]
[234, 122, 294, 71, 204, 360, 359, 318, 273, 212]
The above code creates 10 random integers for you to work with. If you want a set, you can just use the set function to get one, but I think its important for you to understand what set is and what it does. Documentation.
Based on the description of assigment, you needn't initialize set with something. You should only add elements in set in each test and check size of set and number of insertions.
That why init should be like this:
import random
room = range(0, 365)
mySet = set()
P.S. Your code below initialization isn't correct
You have an error because you are creating a set object from an int.
A set should be created from an iterable (like a list) not a single object:
So instead of this :
mySet = set(r)
You should do this :
mySet = set([r])
Why don't you follow the Notes from your homework ?
Notes
For each test, you should use Random.randint to pick a number
between 0 and 365 to use that represents a birthday
randint() returns a random integer without having to create a list, which is what is required with the function you are using :choice()
Here is three examples actually.
>>> result = []
>>> for k in range(10):
>>> result += k*k
>>> result = []
>>> for k in range(10):
>>> result.append(k*k)
>>> result = [k*k for k in range(10)]
First one makes a error. Error prints like below
TypeError: 'int' object is not iterable
However, second and third one works well.
I could not understand the difference between those three statements.
In-place addition on a list object extends the list with the elements of the iterable. k*k isn't an iterable, so you can't really "add" it to a list.
You need to make k*k an iterable:
result += [k*k]
result is a list object (with no entries, initially).
The += operator on a list is basically the same as calling its extend method on whatever is on the right hand side. (There are some subtle differences, not relevant here, but see the python2 programming FAQ for details.) The extend method for a list tries to iterate over the (single) argument, and int is not iterable.
(Meanwhile, of course, the append method just adds its (single) argument, so that works fine. The list comprehension is quite different internally, and is the most efficient method as the list-building is done with much less internal fussing-about.)
You are iterating over an integer rather than a string or sequence.
For result += k*k,only if k was a string/sequence input,then it would be true but if k is a number, result would be a continued summation.
For result.append(k*k),whether k is a string or number,result gets sequentially additions.
I know this is too old but for anyone who lands here, this is a simple reproducible example to illustrate ''int' object is not iterable' error.
lst1 =[3,4,5,6]
def square(lst1):
lst2 = []
for num in lst1:
lst2.append(num**2)
return lst2
#print(list(map(square,lst1))) # this will raise ''int' object is not iterable'
print(list(map(square,list(lst1)))) # here making lst1 as list of list fixs the iterable problem i.e lst1 =[[3,4,5,6]]